Skip to main content
Software Engineering

Software Processes

Published: 2026-08-16
Level: postgraduate
Audience: Postgraduate students in Software Engineering

Prerequisite Knowledge

This lecture builds on the following concepts from earlier lectures. If any feel unfamiliar, review the linked notes before proceeding.

Previously Covered in This Subject

  • What a software process is and its four fundamental activities — covered in Lecture 1 (Introduction to Software Engineering)
  • Reuse-oriented development — covered in Lecture 1 (Introduction to Software Engineering)

# Software Processes

Think about the last time you built something by hand — a piece of furniture, a garden shed, a batch of cookies. You did not simply start hammering; you followed a set of steps in a sensible order, and when a step went wrong you went back and adjusted. Building software works the same way, except the "steps" are far more elaborate, the teams are bigger, and the customers change their minds. A software process is the coherent set of activities that produces a software system — the ordered, repeatable way a team turns an idea into working, maintained software.

This material covers:

  • What a software process is and the four fundamental activities every process contains — specification, development, validation, and evolution
  • How processes are described (work products, roles, preconditions and postconditions)
  • The three general software process models — waterfall, incremental, and reuse-oriented development — and when each one fits
  • The main activities inside specification (requirements engineering), development (design and implementation), validation (testing), and evolution (maintenance)

The thread running through the whole lecture is this: there is no single process that fits every project. Choosing and shaping the process — or a blend of processes — to match the software, the people, and the constraints is itself a core engineering skill.

2.1 What Is a Software Process?

Hook: A contractor builds houses from blueprints; a chef works from recipes. Why can't software engineers just follow one fixed procedure for every project? Because every software system — an airplane's flight-control software, a bank's ledger, a shopping app, a hospital's patient records — is a different beast, with different users, different risks, and different rules. Yet every one of those projects still runs on the same four underlying activities, just arranged differently.

2.1.1 Definition and the Four Fundamental Activities

A software process (the set of related activities that leads to the production of a software system) is the backbone of every software project. In any engineering activity you perform a sequence of activities, and building software is no different. There is, however, no universal one-size-fits-all software engineering method that works for every kind of software product or system, and so no universally applicable software process exists. The process a company uses on a given project depends on the type of software being developed, the requirements of the customer, the skills of the people writing the software, and the operational constraints — the platform the software must run on, the time available, the budget, and so on.

Even though processes vary widely, all of them must include, in some form, the four fundamental software engineering activities:

The four fundamental activities — every software process contains all four, in some form:

  1. Software specification — the functionality of the software and the constraints on its operation are defined. This is the "what should the system do, and what limits must it respect?" step. If a bank's system must handle 10,000 logins per minute and never double-pay a bill, that is part of the specification.
  2. Software development — software design and implementation: the software that must meet the requirements specification is designed and then implemented, that is, developed or produced. Design asks "how should the pieces fit together?"; implementation asks "what exactly should each piece do in code?"
  3. Software validation — the software is validated to ensure that it does what the customer wants. Validation checks the built system against the specification and against the customer's real expectations — not just against what the developers thought was asked.
  4. Software evolution — the software must evolve to meet the changing needs of the customer, as the system and the business needs around it grow and change. Software keeps being changed for as long as it lives — new laws, new markets, new users, new bugs found in the field.

The four activities form a natural arc: decide what to build (specification), build it (development), check it (validation), and keep it alive (evolution).

These four look simple, but each is a very complex process in its own right. They contain many sub-activities, such as requirements elicitation, requirements specification, requirements validation, architectural design, high-level design, low-level design, unit testing, and integration testing. The processes also include supporting activities — software configuration management, software project management, and software quality management — that support development throughout the lifecycle and through the later maintenance and evolution of the system.

  • Requirements elicitation (how you gather what users need) and requirements validation (how you check those needs are right) are sub-activities of specification.
  • Architectural design (the overall skeleton), high-level design (subsystems), and low-level design (individual modules) are sub-activities of development.
  • Unit testing (checking one component) and integration testing (checking components working together) are sub-activities of validation.
  • Configuration management (tracking versions of code and documents), project management (planning, staffing, budgets, progress), and quality management (setting and checking quality standards) run alongside the whole lifecycle rather than belonging to any single phase.

Intuition: Think of the four activities as the four seasons of software — you plan the year (specification), plant and grow (development), harvest and inspect (validation), and keep the orchard productive for years (evolution). Every farm follows this cycle; no two farms run it identically, because soil, crops, and markets differ. The analogy breaks where software is concerned: unlike seasons, the activities loop back on each other many times within a single project, and "winter" never ends — evolution runs as long as the system runs.

2.1.2 Describing a Process: Work Products, Roles, Preconditions, and Postconditions

When we talk about software processes we usually describe the activities themselves — defining a database, designing a database, designing user interfaces, or the ordering of these activities — because everyone can relate to what people actually do to develop software. But a full process description must say more than what is being done. It must also say who is involved, what the input is, what the output is, and what conditions influence the sequence of activities.

A process description may also include:

  • Work products (also called deliverables) — the outcomes of a process activity. For example, the outcome of a high-level architectural design activity may be a model of the software architecture. Work products are the visible, reviewable results that let managers and customers track progress.
  • Roles — the responsibilities of the people involved in the process. Examples are software developers, software testing engineers, software project manager, configuration manager, and quality manager. A person may fill several roles, and a role may be shared by several people; what matters is that the responsibilities are clear.
  • Preconditions and postconditions — for every activity there is a precondition that must hold before the activity is enacted (or before a work product is produced) and a postcondition that must hold after. For example, before architectural design begins, a precondition may be that the customer has approved all the requirements; after architectural design, a postcondition is that an architectural model of the system exists.

Intuition for preconditions and postconditions: A precondition is the "before" contract — what must already be true so the activity makes sense — and a postcondition is the "after" contract — what must be true when the activity finishes. Baking a cake: the precondition is "oven is preheated and ingredients are measured"; the postcondition is "a baked cake exists on the counter." If the oven is cold (precondition violated), the cake fails even though every step was executed. In software, jumping into design before the customer has approved the requirements (violating the precondition) reliably produces a system nobody asked for.

Software processes are complex, highly intellectual, and creative. They rely on people making decisions and judgments throughout, which is one more reason no single process suits every organization. Most software companies have developed their own software development processes, and these processes have evolved to take advantage of the capabilities of the developers in the organization and the characteristics of the systems being developed. For very safety-critical systems a very structured development process is required, with detailed records maintained and the design completely verified even before development can start. For interactive business systems, where requirements are likely to change frequently, a more flexible, agile process is likely to work better.

Professional software development is a properly managed activity, and planning is an inherent part of all processes — even the most agile project plans its next steps; only the planning horizon differs.

2.1.3 Plan-Driven versus Agile Processes

A plan-driven development process is one where all the activities of the entire software development lifecycle are planned in advance, and progress is measured against that plan. Resources are allocated, budgeted, and tracked and monitored continuously. This is the characteristic of plan-driven processes: the set of activities for the whole project is fixed up front.

An agile process is incremental and iterative. Here the planning itself is incremental and continual, carried on while the software is being developed, because not all requirements are captured upfront. The initial core requirements might be specified in the first iterations or increments. Because planning is continual, it is easier to change the process to reflect changing customer or product requirements. Agile methods are discussed in detail in a later session.

The lecture contrasts the two approaches directly — this is one of the most repeated distinctions in the whole session:

Dimension Plan-driven process Agile process
Planning All lifecycle activities planned up front; the plan is fixed before development starts Planning is incremental and continual, carried on during development
Requirements Captured and fixed early (in principle) Not all captured upfront; core requirements settle in the first increments
Progress measurement Measured against the plan; resources allocated, budgeted, tracked continuously Measured against working software produced in each increment
Responding to change Change is expensive; it means rework against the plan Change is easier, because the plan itself adapts
Typical fit Safety-critical, embedded, large coordinated projects Interactive business systems with frequently changing requirements

When to pick which: choose plan-driven where the cost of getting something wrong is huge and the requirements can be pinned down; choose agile where requirements will keep moving and feedback is cheap. For large software systems — systems of systems — you generally need to find a balance between plan-driven and agile approaches for the various parts of the system: the well-understood core can be planned, while the uncertain edges evolve.

2.1.4 Process Improvement

There is always scope for process improvement in any organization. Processes may include outdated techniques, or they may not take advantage of the best practices of industrial software engineering — many organizations still do not apply best practices in their regular development activity. Organizations can improve their processes by adopting techniques and tools such as UML-based processes and test-driven development. These aspects come up again when process improvement is discussed.

Common pitfalls:

  1. Treating the process as a straightjacket. A process is a tool, not a religion. Copying a competitor's process wholesale, without adapting it to your people, platform, and project type, usually creates paperwork without progress.
  2. Assuming "plan-driven" means "no changes." In practice even waterfall projects renegotiate; the difference is that in plan-driven work a change is expensive and goes through formal re-approval, not that it never happens.
  3. Confusing the four activities with a fixed order. Specification, development, validation, and evolution appear in every process, but in agile processes they are interleaved, not sequenced. The activities are the ingredients; the process is how you cook them.
  4. Believing every project needs a full documented process. A small two-week tool with one developer does not need the ceremony of a safety-critical avionics project — matching the process to the scale of the work is part of the skill.

Recap: A software process is the set of related activities that produces a software system. Every process contains the four fundamental activities — specification, development, validation, and evolution — and no universal process fits all projects; you choose and adapt based on the system, the customer, the people, and the constraints. A full process description names the work products, roles, and pre/postconditions, and the plan-driven-versus-agile spectrum captures the two great planning philosophies.

Exam note: The four fundamental activities (specification, development, validation, evolution) and the claim that no universal process exists are core knowledge this session keeps returning to — expect to reproduce both and to explain what each activity contains.

Real-world connection: Every piece of software you use today ran through all four activities, arranged by some process. A car's engine-control unit was developed with a heavy, heavily documented plan-driven process, because a silent failure in the steering software could cost lives. The social media app on your phone was built incrementally — features shipped in weekly increments, feedback gathered from real users, and evolution continues daily. When you later design operating-system algorithms or lead a team, the concurrency, quality, and configuration-management concerns that processes coordinate will be your daily environment.

2.2 Software Process Models

Hook: A map of a city shows you the streets — but it does not tell you which restaurants are good or where the potholes are. A different map shows the subway lines; another shows the parks. Each map is useful precisely because it leaves most things out. Software process models work the same way: each one is a deliberately simplified picture of a real process, drawn from one particular angle.

2.2.1 What a Process Model Is

A software process model, sometimes called a software development lifecycle (SDLC) model, is an abstract or simplified representation of a software process. A model, by definition, is a representation of a real-world entity or process. Each software process model represents the process from a particular perspective, and so provides only partial information about that process. For example, a process activity model shows the activities and their sequence, but may not show the roles of the people involved in those activities. A roles-and-responsibilities model may show who does what but say nothing about ordering. Neither is "wrong" — each is incomplete by design, and that incompleteness is what makes the model readable.

Process model (SDLC model) = an abstract, simplified representation of a software process, showing one perspective at a time.

  • Abstract means the messy reality is compressed: dozens of micro-activities collapse into a handful of stages.
  • Simplified means detail is deliberately discarded — the model shows the skeleton, not the flesh.
  • Perspective means every model answers one question well (what happens next? who is responsible? what documents are produced?) and ignores the others.

Remember the city map: the street map (the activity model) and the subway map (the deliverable model) describe the same city from different angles, and both are accurate.

The general process models, sometimes called process paradigms, are high-level abstract descriptions of software processes that can be used to explain different approaches to software development. Think of them as process frameworks that can be extended and adapted to create more specific software engineering processes suited to your organization, your project, the resources you have, your people, and the organizational, technical, and social constraints you face. You choose the approaches that are applicable to your organization.

In short: a process model is a template. Your organization takes the template, extends it, and instantiates it into a concrete process with named stages, named roles, and real documents. Two companies can both claim "we use the waterfall model" and run visibly different processes, because both customized the same template differently.

2.2.2 The Three General Process Models

Three general process models are examined here, at a high level: the framework of each process rather than the details of its internal activities. Each of the next several sections digs into one of them.

  1. The waterfall model — assumes the fundamental process activities (requirements specification, software development, software validation, and software evolution) and represents them as separate process phases: requirements specification, software design and implementation, and testing. The phases run one after another, like water falling over ledges.
  2. Incremental development — the system is developed as a series of versions or increments, with each version or increment adding functionality to the previous one. Incremental and iterative development of this kind is the basis for agile development — the sentence that defines the model's place in the process landscape.
  3. Reuse-oriented development — based on the availability of reusable components or systems that can be integrated into an existing or a new system: you configure these components for use and integrate them into the system you want to develop.

Reuse-oriented development is quite common nowadays, because rarely does any professional software development start from scratch — unless you are doing a programming assignment as part of a course. In professional development you usually start with an existing base of code, with libraries and components available within a framework such as .NET or any other application development framework, and you draw on them, integrate them, and configure them to suit your requirements.

The three models differ in how they arrange the same fundamental activities:

Model How activities are arranged Requirements Response to change When you see it
Waterfall Sequential phases, one after another Fixed early, signed off Change means going back through phases Safety-critical, embedded, large coordinated projects
Incremental Specification, development, validation interleaved across versions Core captured early; rest evolves per increment Change absorbed into the next increment Most application systems and software products
Reuse-oriented Configuration and integration of existing components around the requirements Refined around what components offer Change met by swapping/configuring components Business systems, anything built on existing frameworks

2.2.3 No Universal Model: Matching the Model to the System

There is no single process model that is right for all kinds of software. The right model depends on the customer, the requirements, the regulatory requirements, the environment where the software will be used, and the type of software being developed. To take the recurring examples:

Kind of software Model used Why
Safety-critical software Waterfall process A lot of analysis, verification, and documentation is required before implementation can begin; the stages are deep-checked in order
Commercially available off-the-shelf software products Incremental process model Requirements evolve with market feedback; each version must ship value to customers fast
Business systems Reuse-oriented (configuring/integrating existing systems) Most needed functionality already exists in mature systems; wiring them together is cheaper than rebuilding

The majority of practical software processes are based on a general model — the waterfall, the incremental model, or the reuse-oriented model. This is especially true for large systems engineering. For large systems, which are systems of systems, it makes sense to combine the best features of all three general models. You need information about the essential system requirements to design a software architecture that supports them, so you cannot develop a large system purely incrementally: you need an architectural base, then you develop each module or component one by one, incrementally. Different subsystems inside a large system may have to be designed and developed using different approaches. Parts of the system that are well understood, with fully specified requirements, can be developed using a waterfall model, or bought as commercially available off-the-shelf systems, or taken as reusable components and configured directly into your system. Parts that cannot be specified in advance, because the evolution of the requirements is not clear, should be developed using an incremental approach. In both the waterfall and the incremental model you may also reuse a number of software components, depending on their availability and suitability.

Intuition: A large system is like a large city being developed by many builders. You cannot build the whole city incrementally without a master plan — you need the road network and power grid (the architecture) first. But once the skeleton exists, each neighbourhood can be built its own way: some by strict blueprints (waterfall), some block by block as residents demand (incremental), some by converting existing buildings (reuse). One model alone would be wrong for the city; a mix is right. The analogy breaks where architecture is concerned: software architecture can itself be evolved and refactored, which civil infrastructure cannot.

2.2.4 The Rational Unified Process

Many attempts have been made to develop universal process models that draw on all the general models. One of them is the Rational Unified Process (RUP), also called the unified process, developed by Rational, a US software engineering company. The Rational Unified Process is a framework that can be instantiated in different ways to create processes and process models that resemble any of the general process models, or a combination of them. It has been adapted by some large companies, notably IBM, but it has not been widely adopted. The unified process is looked at briefly in a later session.

The lesson of RUP's history is worth keeping: even the best-engineered universal framework did not achieve universal adoption. Organizations do not adopt a process because it is elegant on paper; they adopt one that matches their people, their contracts, their regulations, and their habits — which is why the "no universal model" claim keeps coming back.

Common pitfalls:

  1. Confusing the model with the real process. A model is a simplified picture; the real process is messier, with feedback, overlap, and people making judgment calls. Judging a process from its diagram alone is like judging a city from its subway map.
  2. Treating "incremental development" and "agile" as unrelated ideas. Incremental, iterative development is the technical basis for agile methods — agile is the incremental model plus a particular philosophy of planning, feedback, and minimal overhead.
  3. Forgetting that models combine. "Which model should we use?" is often the wrong question. Professional practice, especially in large systems, blends all three — a waterfall core for the well-understood subsystems, incremental development for the uncertain parts, and reuse everywhere it fits.
  4. Reading the model list as a menu of mutually exclusive choices. All three models share the same four fundamental activities; they differ only in how those activities are arranged and interleaved.

Recap: A software process model is an abstract, simplified representation of a real process — one perspective at a time, like a city map. Three general models dominate: waterfall (sequential phases), incremental development (interleaved activities across versions; the basis of agile), and reuse-oriented development (configuring and integrating existing components). No model is universally right: the fit depends on the system type, the customer, the regulatory environment, and the people — and large systems usually combine all three. RUP, a framework that tried to unify the general models, was adapted by IBM but never widely adopted.

Bridge: With the landscape in place, the next sections zoom into each model one by one — first the waterfall, the classic sequential model and the reference point the other two are measured against.

Real-world connection: Process models are not academic decoration — they shape real engineering budgets and careers. Aviation and medical-device suppliers certify their processes precisely because regulators must audit the waterfall-style record trail before a chip or a drug pump ships. Product companies like web-app vendors run continuous incremental delivery: weekly releases, each a new increment. Enterprise IT departments spend most of their time configuring and integrating existing systems — the reuse-oriented model — because rebuilding a payroll system from scratch would be commercial suicide. When you interview for a software role, "what process does your team use?" is a genuine, meaningful question about how the team's work will be planned and controlled.

2.3 The Waterfall Model

Hook: Why would a software team deliberately refuse to accept changes to requirements for months? Because some systems — the software inside a car's braking controller, a hospital ventilator, a military radar — simply cannot tolerate a design that shifts mid-build. For those systems, the waterfall model's strict order is not a weakness; it is the whole point.

2.3.1 Origins and Overview

The classic waterfall model draws on classic engineering approaches, specifically traditional hardware engineering, where you specify the requirements, design, create a high-level design, then do the implementation, then the testing and integration, and then operation and maintenance. It was the first published model of the software development process, derived from the engineering process models used in large systems engineering. It presents software development as a number of stages, and because of the cascade-like appearance flowing from requirements downward, it became known as the waterfall model of the software development lifecycle.

The waterfall model is an example of a plan-driven process: every activity is planned well in advance, resources are allocated, and progress is tracked and monitored periodically by the managers concerned. In principle, you plan and schedule all process activities before starting software development.

Different sources show many variants of this classic model — searching images for "waterfall model" turns up countless adapted versions, and organizations adapt the model to their needs. The simplified version used here is just one example.

The waterfall diagram (visualize it): picture five rounded rectangles stacked vertically, one per stage, from top to bottom: requirements definition, system and software design, implementation and unit testing, integration and system testing, operation and maintenance. A solid arrow runs downward from each box to the next — the forward flow. There is also a backward feedback flow: from each stage, a dashed arrow loops back up to the previous stages. The layout reads like water cascading down a series of ledges — that is where the name comes from. The one-sentence takeaway: the diagram shows both the ideal downward sequence and the practical reality that information flows backward whenever a later stage discovers a problem in an earlier one.

2.3.2 The Five Stages in Detail

The five stages directly reflect the four fundamental activities — specification appears as the first stage, development as stages 2–3, validation as stage 4, and evolution as stage 5.

Stage 1 — Requirements analysis and definition. You specify the system services, the constraints on its development and operation, and the goals for the product, in consultation with the system users. These are then refined and defined in detail, and a detailed system specification, or software requirements specification, is prepared at the end of this phase. The output is the contract the rest of the process will be judged against.

Stage 2 — System and software design. Once the requirements are agreed and signed off between the client and the developers, you do the system design and software design, which includes the high-level architectural design as well as the detailed design of the modules. In systems engineering, requirements are allocated to either hardware or software, and an overall system architecture is established. Software design identifies the fundamental software system abstractions, the architectural components and their relationships, and then elaborates the architectural design into a more detailed design with sub-modules and components that interact with each other, as you do in object-oriented analysis and design.

Stage 3 — Implementation and unit testing. Once the design is agreed and verified as correct and complete with respect to the requirements, the software design is realized as a set of programs, modules, or program units. Unit testing is done by the programmers themselves, verifying that each unit or program meets its specification. "Unit" here means one independently buildable piece — a module, a class, a function package — and its test is the programmer's personal quality gate.

Stage 4 — Integration and system testing. The individual program units or modules are integrated and tested as a complete system, to ensure that the software requirements are met as a whole, as stated in the requirements specification. This stage involves various types of testing — integration testing, system testing, and acceptance testing — and after it, including acceptance testing, the software system is delivered to the customer.

Stage 5 — Operation and maintenance. Once the system is delivered it is put into operation, and it then undergoes continuous maintenance: changing requirements, fixing bugs, and so on. This is the longest lifecycle phase. Maintenance involves correcting various errors that were not discovered in earlier stages of the lifecycle, improving the system units, enhancing the system services whenever new requirements are discovered, and enabling the system to remain strong and serve a long, productive, and useful life.

Two analogies that carry the whole model:

Human life cycle. Like a human life cycle, where the child's birth is the handing over of the product and the rest of life evolves and changes throughout with many changing needs, the software serves its purpose over a long life. The "birth" (delivery) is a single dramatic moment; the life that follows — decades of growth, adaptation, and repair — is where most of the story actually happens. This analogy breaks in one way: a child does not choose its own requirements, but software's whole point is serving the changing needs of its users.

The iceberg. A vivid way to see this: the entire software development lifecycle up to delivery — requirements specification, system and software design, implementation and unit testing, integration and system testing — is only the tip of the iceberg. Operation and maintenance, where the software serves its useful life, is the whole mass of the iceberg below the surface of the ocean. Because maintenance cost is high throughout the software's life, it is important to spend quality time developing proper requirements, verifying the design, implementing and testing adequately, and delivering a product that is maintainable, so that maintenance costs stay manageable.

The iceberg picture carries a practical lesson: the part of the system you see (development) is cheap compared with the part you don't see (maintenance). Every hour spent getting requirements, design, and tests right is hours saved in the maintenance mass below the waterline.

2.3.3 Sign-Off and Feedback between Stages

In principle, the result of each phase of the waterfall model is one or more documents that are approved and signed off between the client and the developer, and the next phase cannot start until the previous phase has finished. This comes from the earlier hardware development process, where manufacturing costs are high, so it makes sense to sign off the requirements and the design once they are verified, and to sign off testing, and so on.

For software, however, these stages overlap and feed information to each other, through forward-feeding information and feedback arrows. During design, problems with requirements are identified; during coding, certain design problems are found; and so on. In practice the software process is never the simple linear sequence the waterfall diagram suggests, with arrows moving only from requirements to design to implementation to testing to operation and maintenance. Instead there is feedback from one phase to another — from operations back to implementation, testing, design, or even to requirements. As new information emerges during the process, the documents produced at previous stages should be modified to reflect the required system changes. For example, if it is discovered that a requirement is too expensive to implement, the requirements document should be changed to modify or remove that requirement. That requires customer approval and causes delays in the overall development process.

Why the feedback arrows matter: the waterfall is a sequential model with feedback, not a naive one-way pipe. The diagram's backward arrows are not decoration — they are the model's honest admission that design discovers requirement errors, coding discovers design errors, and operations discovers everyone's errors. The discipline of the model is that these corrections still go through the formal documents and sign-offs, which is what makes them visible and expensive — and what makes premature freezing (next section) so tempting.

2.3.4 Renegotiating Requirements and Premature Freezing

Q: Have you come across situations where you had to renegotiate the requirements during design — once you started doing the design — when a requirement felt too difficult to implement, or challenging within the given time and budget — and so you had to reduce the scope or scale, remove some features, or at least modify certain requirements and get the customer's sign-off before proceeding? A: Yes, this kind of renegotiation happens regularly in day-to-day work. But this back-and-forth negotiation will delay the project, and it may lead customers and developers to prematurely freeze the requirement so that no further changes are made — they say "this is it," even though it may not be what the customers or end users really want. Prematurely freezing requirements avoids the delay, but it leaves the problems for later resolution, or the problems are ignored, or they are worked around. This may mean the system will not do what the end user wants, and it may also lead to badly structured systems, because design problems are circumvented by implementation tricks where the design is difficult to implement, and the result may not meet the actual requirements.

The exchange above captures a real tension: every requirement change costs delay and paperwork in a plan-driven project, so both sides feel pressure to declare "this is it" and stop changing. But that freeze does not make the problems disappear — it pushes them into the future, where they surface as user disappointment, hacked-together workarounds, or systems that quietly fail to do what people actually needed.

Q: Have you come across situations in coding and implementation where certain design problems were circumvented by implementation tricks — for example, when something is hard coded when it should be accepting a variable — or where some trick is applied to bypass an incorrect requirement or design specification? A: It happens. When you cannot go back and change the requirements or the design specification, you bypass the problem in the implementation and achieve the results some way or other, and only the programmer understands what he has done to do that. Hard coding is one such trick: the programmer bypasses the design so that only the programmer understands what was done. This happens quite often, especially when there is no time and you have to prepare for user acceptance testing quickly.

Hard coding (writing a fixed value into the code where the design called for a configurable input) is the classic signature of this failure mode: the system works today, in the one situation the programmer tested, and nobody else can tell why. When the design was wrong but frozen, the implementation quietly carries the debt. The professor's point is not that programmers are careless — it is that a process which blocks legitimate design corrections forces this behavior on its own developers.

During the final lifecycle phase of operation and maintenance, the software is put into use. Various errors and omissions in the original software requirements are discovered, programming errors, bugs, and design errors emerge, and while the system is in operation the users realize that this is not exactly what they wanted, and new requirements emerge. So the system must evolve to remain useful. Good systems survive for long; it is bad software that does not serve its purpose that is discarded soon. You may have to repeat all the previous process stages, starting from requirements, but in reality the software has to be flexible and accommodate change while it is being developed.

2.3.5 When the Waterfall Model Fits (and When It Does Not)

The need for early commitment to a fixed requirement, and the rework involved when changes are made, mean the waterfall model is appropriate only for certain types of systems: safety-critical systems and embedded systems.

Worked example — the embedded systems chip. Consider the engine-control unit (ECU) that manages fuel injection in a car, with its software permanently programmed into the ROM (read-only memory) of the hardware chip:

  1. The requirements are captured and verified: the ECU must sample engine sensors 100 times per second, compute the optimal fuel mix, and react to a knock sensor within 10 milliseconds.
  2. The design is verified against those requirements — every timing budget and every sensor interface is checked before any code is written.
  3. Only then is the code compiled and programmed into the ROM of the hardware. Once the chip is burned, the software is physically unchangeable — there is no "patch over the air" for a chip soldered into an engine bay.
  4. The chip is tested, integrated, and shipped, and then it must simply work, for years, in heat, cold, and vibration.

No further interaction or change: the software has to do its specific task on the chip. Because the software must interface with hardware systems, and hardware is inflexible, it is usually not possible to delay decisions on software functionality until implementation time. Sense-check: every stage's output is verifiable before the next starts, and verification before burning is the only protection the project will ever get — once the ROM is written, the waterfall's "rework" arrow is no longer available.

For safety-critical systems there is a need for extensive safety and security analysis and verification of the specification as well as the design, sometimes including formal verification, that is, verification against a mathematical model. In these systems the specification and design documents must be thorough and complete so that this analysis is possible. Safety-related problems in the specification and design are usually very expensive to correct at the implementation stage or even after implementation.

Worked example — the vehicle recall. The stakes of getting safety-critical software wrong after implementation are shown by real recalls of leading car brands. When a defective chip or defective software is found in a shipped vehicle line, the manufacturer must recall the vehicles — in the 2009–2011 unintended-acceleration recalls, a leading brand recalled roughly 9 million vehicles worldwide; the total bill, including corrections, legal settlements, and lost production, reached into the billions of dollars. Walk through the failure chain:

  1. A defect in the electronic throttle software (or its interaction with the hardware) is discovered only in the field, years after the chip went into production.
  2. Every vehicle with that chip is potentially dangerous, so all of them — not the one defective unit — are recalled.
  3. The hardware and software must be corrected and re-verified, and the corrected parts must be installed in every recalled vehicle.
  4. The manufacturer pays for the parts, the labor, the logistics, and the lost trust.

The lesson: at the implementation stage or after, a safety-related flaw can cost more than the entire development project. This is why waterfall-style thoroughness — complete specification and design documents, verified before development — is the price of admission for such systems, and why formal verification is used in the most critical cases.

The waterfall model also suits large software systems that are part of broad systems engineering projects including both hardware and software, with many partnering companies involved in the development. The hardware in such systems may be developed using a model similar to the waterfall model, and companies find it easier to apply one common model, like the waterfall, for both hardware and software. When several companies are involved, complete specifications may be needed even to distribute the work: independent development of different subsystems by different contractors needs a complete specification.

The waterfall model is not the right choice where informal team communication is required and possible, and where the software requirements keep changing quickly. For systems with a lot of user interaction, iterative or incremental development and agile methods are much better.

In short, the waterfall model is mostly applicable when the requirements are well understood and changes during the design process are likely to be fairly limited, and for large systems engineering projects that need coordination of work among different developers.

2.3.6 Formal System Development

One variation of the waterfall model — or one component of it — is formal system development. You develop a mathematical model of the system specification, refine it using mathematical transformations that preserve its consistency, and then translate it into executable code using automated code converters from the mathematical specification to code, which preserves correctness. Because of the high cost of developing a formal specification, this development model is very rarely used, except for highly safety-critical systems engineering.

The logic of the approach: if the specification is a mathematical model, and every refinement step provably preserves consistency, and the code is generated automatically from the final model, then correctness is preserved by construction from specification to code. The price is that building the mathematical specification is slow, needs highly specialized people, and demands complete requirements up front — which is exactly why formal development only appears where the cost of a defect is catastrophic. A refinement step counts as safe only if it provably keeps the model consistent; skipping that proof, or letting the model drift from the real requirements, silently destroys the guarantee.

Common pitfalls:

  1. Reading the waterfall diagram as the whole truth. The real process is not a linear sequence — there is feedback from every stage to the earlier ones, and documents get revised as problems surface. The diagram is the ideal; the feedback arrows are the reality.
  2. Believing sign-off means certainty. A signed-off requirements document is an agreement, not a guarantee. Both sides sign partly to keep the project moving, and the real requirements may still be wrong.
  3. Freezing requirements to dodge delay. Prematurely freezing hides the problems — they resurface later as user dissatisfaction, bad system structure, and implementation tricks like hard coding that only the original programmer understands.
  4. Using waterfall where requirements churn. If the requirements change quickly and the team communicates informally, the waterfall's rework cost punishes every change. Interactive systems belong with incremental or agile approaches.
  5. Assuming formal development is "better." Formal system development guarantees consistency of the model but is so expensive that it is reserved for the most safety-critical work — using it on a routine business system would burn the budget without proportionally better results.

Recap: The waterfall model turns the four fundamental activities into five sequential, signed-off stages (requirements analysis and definition; system and software design; implementation and unit testing; integration and system testing; operation and maintenance). In principle each stage ends with an approved document and the next stage cannot start; in practice feedback arrows carry discoveries backward. The model fits embedded systems, safety-critical systems, and large multi-company engineering projects — where requirements are well understood and change is limited — and fails where requirements churn. Its costs (renegotiation delays, premature freezing, implementation tricks) and its most rigorous variant (formal system development) all follow from the same commitment to early, fixed requirements.

Exam note: Know the five stages in order, the sign-off principle, why feedback makes the real process non-linear, the consequences of premature freezing and implementation tricks, when the model is appropriate (embedded, safety-critical, large systems) and when it is not — and the iceberg/human-lifecycle analogies that explain why operation and maintenance dominate the lifecycle.

Bridge: The waterfall sequences everything. The next model inverts that choice: instead of freezing the whole system up front, it interleaves specification, development, and validation and grows the system version by version.

Real-world connection: The waterfall's discipline lives on wherever failure is unforgiving — avionics, medical devices, railway signaling, nuclear-plant control. Regulatory bodies audit the sign-off documents themselves; the process record is part of the deliverable. And the human-lifecycle point is worth remembering when you choose a career path: roughly two-thirds of a professional software developer's effort typically goes into evolving existing systems, not building new ones — the iceberg is real, and most of your working life will be spent below the waterline.

2.4 Incremental Development

Hook: Suppose you must build a system you cannot fully describe yet — you know the rough shape, but the details will only become clear once users see something working. Do you wait months to write one perfect specification? Or do you ship a small piece, watch what happens, and build the next piece on what you learned? Incremental development bets everything on the second answer.

2.4.1 Core Idea: Concurrent Specification, Development, and Validation

A process model is an abstract diagram representing the sequence of activities, or the arrangement and flow of activities, within the process. The waterfall model is a linear sequential model with feedback from each stage to the previous stages. In the incremental model, the three main activities — requirements specification, software development, and software validation — are concurrent activities. There is feedback from each to the others and feed-forward from each to the others, moving back and forth in an iterative, incremental manner, producing many intermediate versions before the final version of a particular module or increment is released.

Incremental development starts with an outline description, not a detailed specification, and it is intended for interactive systems where the requirements are frequently going to change. The idea is simple: develop an initial implementation, get feedback from the users and other stakeholders, and the software evolves through several intermediate versions until the requirements for that particular module are met, so that a final version is developed as the first increment. This first increment may undergo further changes as the software gets developed. The key point is that specification, development, and validation are concurrent: a module may be specified partly, implementation of that part can begin, and it can even be validated and tested, while the next part of the module is specified, developed, and incremented.

The incremental development diagram (visualize it): three horizontal streams — specification at the top, development in the middle, validation at the bottom — flow left to right, with arrows crossing between them in both directions, so information moves from any stream to any other. The process starts on the left with an outline description (not a specification). Working across the three interleaved streams, the system passes through intermediate versions (each a partially complete system) until it reaches the final version on the right. The one-sentence takeaway: while the waterfall draws one pipeline, this diagram draws three parallel pipes with constant cross-traffic — the activities genuinely overlap in time.

2.4.2 Concurrent versus Parallel

Q: Are the activities in this model parallel, or concurrent? Aren't concurrent and parallel the same thing? A: No — and this is the key correction: concurrent and parallel are not the same thing. The distinction matters, because parallel activities are all carried out simultaneously, at the same time — and that is not possible here: you cannot do all the specification, all the development, and all the implementation at once. Concurrent means that the activities are interleaved in time. They may be interrelated, but they are arbitrarily interleaved in time: some modules are under specification while others are under development and still others are under validation, and they all go through multiple iterations in the meantime. The term for "arbitrarily interleaved in time" is concurrency. This difference is an important component of knowledge in computing systems, especially when you design algorithms for operating systems, where you deal with concurrent processes as well as parallel processes. Study tip: it is worth Googling the difference between parallelism and concurrency to get it clear.

So specification, development, and validation are interleaved in time rather than run in parallel, with rapid feedback across all the activities.

The correction sticks because the two words sound interchangeable, but they describe different machines. Parallel execution means several things literally happen at the same instant — two threads on two cores, two assembly lines side by side. Concurrent execution means several things are in progress during the same time window, taking turns — one thread waiting for input while another computes, a chef who starts the rice, then chops vegetables, then returns to the rice. In the incremental model, specification, development, and validation do not all run simultaneously; they take turns, interleaved, and each feeds the others.

2.4.3 How Increments Are Chosen and Evaluated

In some form, incremental development is the most common process model. It is the same as the agile approach to development, and it is the most common approach for developing application systems and software products. It can be plan-driven, agile, or usually a mixture of both: in a plan-driven approach the system increments are identified in advance; in an agile approach the early increments are identified, but the development of later increments depends on the progress of the project and the customer's priorities.

Incremental software development, which is a fundamental part of agile development methods, is better than the waterfall approach for systems whose requirements are likely to change during the development process — which is the case for most business systems and software products. It also reflects the way we actually solve problems. We rarely get the complete set of requirements at the outset, and we rarely work out a complete problem solution for a complex system well in advance. Instead we move towards a solution in a series of steps, tackling one component at a time and backtracking when we realize we have made a mistake or hit a dead end. Developing software incrementally is also more manageable, cheaper, and makes changes easier than trying to develop a complete system as a whole — although, as we will see later, the waterfall model also allows a lot of flexibility.

Each increment or version of the system incorporates some of the functionality the customer needs. Generally, the early increments include the most important, most critical, or most urgently required functionality.

Worked example — a financial accounting system. Suppose you are building a financial accounting system for a company that currently runs its books on spreadsheets. The full system will eventually handle invoicing, payroll, bank reconciliation, tax reports, and dashboards. How do you choose what comes first?

  1. List the candidate increments: accounts receivable (money customers owe you), accounts payable (money you owe suppliers), bank reconciliation, tax reporting, dashboards.
  2. Rank them by business criticality. The accounts receivable and accounts payable components are the most fundamental parts: without them, the company cannot record who owes what or what it owes — every other feature reads or writes that data. So they are delivered first, and the more elaborate banking or financial system components are built on top of them.
  3. Build and deliver increment 1 (accounts receivable and accounts payable). The customer now has working core functionality — they can enter invoices, record payments, and see outstanding balances.
  4. Evaluate with the customer. They can check at an early stage whether the system delivers the required functionality and features. If it does not, only the current increment has to be changed, and new functionality can be defined for later increments — no redesign of an unbuilt system is wasted.
  5. Continue: reconciliation, then tax reports, then dashboards, each built on the verified core.

Sense-check: the first increment already earns its keep in day-to-day business, and a wrong guess about a later feature (say, the dashboard layout) costs only that increment's rework, not the whole project. That is the economic core of incremental development: pay for each slice as it is proven, not for the whole cake in advance.

2.4.4 Advantages over the Waterfall Model

Incremental development has several advantages over the waterfall model:

  • The cost of accommodating requirements changes is much reduced, because you are working in smaller chunks, and even if a change is not found to meet the requirements you can modify it in the next increment.
  • The amount of analysis and documentation that has to be redone is significantly less than with the waterfall model, where you try to capture the complete specification up front and then design the complete system architecturally and in detailed design.
  • With smaller increments it is easier to get customer feedback on the development work done. The customer can comment on demonstrations of the software and see how much has been implemented and what the progress is. With only a design document or a requirements specification, the customer cannot appreciate the progress — unless they see something working, even a prototype, they cannot appreciate work in progress from design documents alone.
  • You get early delivery and deployment of useful software to the customer. If a module's requirements are well understood and the module is critical or urgent for business needs, the customer can start using it and gain some value — and some experience with the software — much earlier than with the waterfall model, where you specify all requirements, design the complete system, implement it, test it, and deliver it after a long time.

Scope — when incremental development is the wrong tool: the interleaved, fast-changing style assumes the system can be shaped as it grows. It does not fit every system. For very large systems built by teams in different locations, the teams need a stable architecture and precisely defined responsibilities agreed before the increments — you cannot grow the skeleton incrementally. For embedded systems whose software depends on hardware development, the hardware's inflexibility forces early software decisions. And for some critical systems, all requirements must be analyzed up front to check for interactions that may compromise safety or security. In these cases the model is used in its plan-driven form, with increments identified in advance — or not used at all.

2.4.5 Management Problems and Structural Degradation

From a management perspective, there are problems too — and software engineering is not only about design, development, and testing; it also involves software project management, quality management, and configuration management. A manager needs regular visible work products to measure progress. When systems are developed quickly without documentation, it is hard to produce documentation for each version on a daily basis, so documentation is rarely updated, especially when incremental, iterative (agile) models are followed. You end up with an incomplete product — some modules delivered, developed, and tested — but you cannot sign off on a prototype, you need some documentation, and the process is not as visible as it is in the waterfall model.

The second problem comes from rapid changes in the implementation, the requirements, and the design, without a stable architectural design as the basis for constructing the whole software system. Because the design and the requirements keep changing, the system structure — the core architectural structure — tends to degrade as new increments are added. Regular change leads to messy code, as new functionality is added in whatever way is possible, sometimes in a jury-rigged way, just so that it works and meets the requirements. Over time it becomes increasingly difficult and quite expensive to add new features, because the code becomes too difficult to manage, it is not refactored, and it is not quite understandable; add a new requirement and the code tends to collapse.

So the incremental model trades one cost for another: it lowers the cost of change but raises the cost of chaos. The waterfall spends heavily up front to keep the structure clean; the incremental model must spend continuously to keep the structure from rotting.

2.4.6 Refactoring and the Woodpecker Warning

To reduce structural degradation and general code messiness, agile methods suggest that you regularly refactor: improve and restructure the software periodically so that it stays understandable, reliable, and clear, and easier to code and develop. Refactoring (restructuring existing code without changing what it does) is the maintenance discipline that pays the structural debt the increments accumulate.

The need for this was captured by one of the earliest software engineers, back in the 1970s, who observed that system structure tends to degrade with constant tinkering of code, and put it succinctly:

"As if builders built buildings the way programmers tend to write programs, then the very first woodpecker that comes along would destroy the entire civilization."

Think about the programs you wrote years ago — can you still understand them? And if many people work on the code together and the structure degrades, can you still make changes and keep the code strong and reliable? The system structure tends to degrade as you try to add new increments without refactoring and redesigning the system.

These problems are particularly acute for large, complex, long-lifetime systems where different teams develop different parts of the system. Large systems need a stable framework or architecture, and the responsibilities of different teams working on different parts of the system need to be defined precisely with respect to that architecture, planned well in advance rather than developed incrementally.

2.4.7 Incremental Development versus Incremental Delivery

Incremental development does not mean you have to deliver each increment to the customer. You can develop the software system incrementally and expose it to customers and stakeholders for feedback and comments, without necessarily delivering or deploying the software in the customer's environment. There is also incremental delivery: the software is actually deployed into the real operational environment, so that user feedback is likely to be more realistic. Providing feedback through real deployment is not always possible, though, because experimenting with the new software can disrupt all the normal business processes.

The practical distinction: development is about how you build (in slices, with feedback); delivery is about where the slices end up (in the customer's real working environment). A team can develop incrementally and demo each increment in a test environment — the customer reacts, but their daily business is untouched. Incremental delivery puts each increment into production, where feedback is more realistic — users genuinely try the software in real workflows — but the risk is disruption: a half-built system sharing the stage with the legacy system can disturb normal business processes, so not every customer will accept that mode.

Common pitfalls:

  1. Thinking "incremental" means "no architecture." Every increment needs a stable architectural base to grow on; a large system built purely incrementally, without a framework planned in advance, collapses into a structure nobody can manage.
  2. Skipping refactoring "because there is no time." Skipping it is exactly what degrades the structure; the cost is deferred to the day a new requirement makes the code collapse. The woodpecker does not care about your schedule.
  3. Equating concurrency with parallelism. Concurrent activities are interleaved in time; parallel activities happen simultaneously. The incremental model interleaves specification, development, and validation — it does not run them at the same instant.
  4. Confusing incremental development with incremental delivery. You can develop in increments without deploying each one; delivery into the real operational environment is a separate choice with its own disruption costs.
  5. Assuming the process is visible to managers. Incremental, documentation-light work hides progress from anyone who measures progress by documents; managers need visible work products, and the model's informality can leave the project invisible.

Recap: Incremental development interleaves specification, development, and validation — the activities are concurrent (interleaved in time), not parallel (simultaneous) — and grows the system through intermediate versions from an outline description. Early increments carry the most critical functionality (the accounting example: receivables and payables first), which cuts change costs, cuts rework, makes progress visible to customers through working software, and enables early value. Its costs are management visibility, documentation decay, and structural degradation — the woodpecker problem — which refactoring and a planned architectural base keep under control.

Exam note: The concurrency-versus-parallelism distinction was explicitly flagged as important knowledge in computing systems — expect it to matter, and be ready to reproduce it (interleaved in time versus simultaneous) with the operating-systems context. Also know the advantages of incremental over waterfall, its management problems, and the development-versus-delivery difference.

Bridge: Incremental development grows the system from scratch in slices. The third general model skips the "from scratch" entirely — the next section builds new systems out of existing ones.

Real-world connection: Incremental development is the default engine of the modern software industry — mobile apps ship every few weeks, web products deploy continuously, and each release is an increment built on user feedback. The concurrency vocabulary also lives at the heart of computing: operating systems juggle concurrent processes (interleaved) and exploit parallel processes (simultaneous on multiple cores), and the same interleaving discipline governs modern system design from cloud schedulers to database transactions.

2.5 Reuse-Oriented Development

Hook: When was the last time you wrote a program without using a single library — no collections framework, no HTTP client, no math library? Probably never. Now scale that habit up to a whole company: why would a business build a payroll system from scratch when mature payroll engines exist to configure? Reuse-oriented development is the professional form of that instinct.

2.5.1 The Idea of Building from Existing Components

Reuse-oriented development is based on the availability of reusable components or systems. You configure these components for use in a new system, and you integrate them into the system that you want to develop. As noted earlier, it is quite common nowadays: rarely does professional software development start from scratch — that happens mainly in programming assignments as part of a course. In professional development you start with an existing base of code, and you have several libraries and other components available within a framework, such as .NET or any other framework for application development. You draw on them, and the developer integrates and configures these components to suit the requirements.

Reuse-oriented development = building a system by configuring and integrating existing reusable components and systems, rather than developing everything new.

  • Reusable means the component was built once, tested, and made available for many systems — a library, a framework, an off-the-shelf application, a web service.
  • Configuring means adapting a general component to your specific needs — setting parameters, choosing features, defining options — without changing its internals.
  • Integrating means wiring the configured components together with any new code you write, so they behave as one system.

The three kinds of things most often reused, from the big end down: stand-alone application systems (general-purpose systems with many features, bought and configured for a particular environment), collections of objects or components developed as packages to be integrated with a component framework (a UI library, a logging package), and web services developed to standard interfaces and invoked remotely over the internet.

Real-world: business systems are increasingly being developed by reusing or configuring existing systems and integrating them to create a new system with the functionality that is required. Commercially available off-the-shelf products are a related idea: instead of building everything yourself, you buy a system that already exists and configure it to your needs. Component selection also shows up inside design: when a team designs a system, one activity is looking for reusable components — if suitable components exist, they are integrated; if not, new components are designed (see the design activities in Section 2.7).

How the reuse process runs (an outline): the team starts from an outline of the essential requirements (not a full specification), then discovers and evaluates candidate components and systems — do they provide the required functionality? The requirements are then refined to reflect what the available components actually offer. If a suitable off-the-shelf application exists, it is configured for the new setting; otherwise reusable components are adapted and any gaps filled by developing new components, and everything is integrated into the new system. Notice the direction of the flow: requirements bend toward what exists. That is the honest price of reuse — and its biggest difference from the other two models.

2.5.2 Reuse inside Large Systems

In large systems engineering, reuse is one of the levers for combining the best features of the three general models. Parts of the system that are well understood, with fully specified requirements, can be developed with a waterfall model, or they may also be bought as commercially available off-the-shelf systems, or taken as a reusable component and directly configured into the system. Parts that cannot be specified in advance are developed incrementally. In both cases — the waterfall model as well as incremental development — you could have a number of software components that are reused, based on their availability and suitability. The choice of how to build each part is an organizational, technical, and commercial decision as much as an engineering one.

The trade-offs of reuse:

  • Less software to develop. Reusing a mature component means less code written, less code tested, and fewer defects of your own making. The obvious payoffs: lower cost, lower risk, faster delivery.
  • Requirements compromises are inevitable. The available components rarely match the ideal requirements exactly, so the requirements are adjusted to what exists. The risk is a system that does not quite meet the real needs of its users — the "it almost does what we wanted" trap.
  • Loss of control over evolution. New versions of a reused component are produced by someone else, on their schedule. The organization using the component does not control when it changes, what it changes to, or when it stops being supported — an old component that your whole business depends on can quietly become a liability.
  • Dependency risk. A component framework like .NET or a third-party service is a strategic bet: your system's fate is tied to the health and direction of that ecosystem.

Recap: Reuse-oriented development builds systems by configuring and integrating existing components — stand-alone applications, component packages, and web services — instead of writing from scratch, which is why almost no professional project starts with an empty folder. In large systems it is the third lever alongside waterfall and incremental development: well-understood parts bought or configured, uncertain parts developed incrementally, and reused components everywhere their availability and suitability permit. The choice per part is organizational and commercial as much as technical.

Bridge: This completes the tour of the three general models. The rest of the session turns from the shape of processes to their contents — starting with the first fundamental activity, specification, and its requirements-engineering activities.

Real-world connection: Look at any large enterprise IT department and you are looking at reuse-oriented development: enterprise resource planning suites configured for a company's accounting rules, customer-relationship systems wired to existing databases, payment gateways and identity services invoked as web services. Even the mobile app on your phone is mostly a thin layer of new code over a stack of reused components — SDKs, cloud services, and open-source libraries. Understanding reuse is also a career skill: "design for reuse" and "evaluate before you build" are everyday professional decisions, not course abstractions.

2.6 Requirements Engineering Activities

Hook: The cheapest bug to fix is the one you never write down. Studies and decades of project lore agree: requirements mistakes — building the wrong thing, or building the right thing for the wrong users — are among the most expensive errors in software, because everything after them is built on top of them. So how does a team figure out, carefully, what the system must do?

2.6.1 Elicitation and Analysis

The first requirements activity is requirements elicitation and analysis: collecting information about what the system must do. This may involve developing one or more system models and prototypes that help you understand the system to be specified. Requirements engineering is discussed in detail in a later session; here the activities are surveyed in brief.

Elicitation is detective work, not dictation. The information comes from observing existing systems in operation, from discussions with potential users and procurers, and from task analysis — breaking down the actual work people do so the system can support it. Often the team also builds one or more system models and prototypes: a model (a diagram of the domain or the data) makes assumptions visible, and a prototype lets users react to something concrete instead of describing what they want in the abstract. Many organizations also run a short, cheap feasibility study before requirements engineering starts, asking whether the system is needed, whether it is technically possible, and whether it is financially realistic.

2.6.2 Specification: User Requirements and System Requirements

Requirements specification is the activity of translating the information collected during requirements elicitation into a document that defines a set of requirements. That set typically has two levels:

Level Who it is for What it says Example
User requirements Customers and end users Abstract statements of the system — what the system should do, in plain business language "The system must let a clerk print an invoice for any customer within two seconds of opening the account"
System requirements Developers A more detailed description of the functionality to be provided: the services the system must offer, its precise inputs and outputs "Invoice subsystem: given a validated account ID, return an invoice document containing line items, taxes, and totals, formatted per template INV-7"

The same capability appears twice at two levels of detail: abstract enough for the people paying, precise enough for the people building. Requirements analysis continues during definition and specification, and new requirements come to light during the entire process, so all these activities are interleaved with each other — the three activities of elicitation, specification, and validation are not a one-pass sequence but an ongoing conversation.

2.6.3 Validation of Requirements

Requirements validation checks the requirements for correctness, completeness, consistency, and realism. During this process the various errors in the requirements are discovered, and the requirements are modified to correct these problems.

The four checks have distinct meanings:

  • Correctness — the requirements describe what the users really need, not what someone assumed they need.
  • Completeness — nothing essential is missing; every important behavior, input, and constraint is captured.
  • Consistency — the requirements do not contradict each other (one requirement must not say "every order is shipped immediately" while another says "orders from the warehouse are held for review").
  • Realism — the requirements can actually be delivered with the available technology, people, budget, and time.

Each error found here is cheap to fix — a sentence in a document. The same error discovered after implementation means reworking design, code, and tests.

2.6.4 Requirements in Agile versus Plan-Driven Projects

In agile methods, requirements specification is not a separate activity of drawing up a requirements specification document; it is seen as part of the system development. Requirements are informally specified for each increment, like a story, just before that increment is developed, and the stories are prioritized. The requirements are elicited from users who are part of the system or who work closely with the development team — most agile teams have an end-user representative.

Q: While there are standard templates prescribed by IEEE for requirements documents, is a single standard template used everywhere? A: It is more dependent on the kind of project and the approaches you use. In agile processes there is no specification document at all: requirements are written as stories and the development is carried out incrementally, so you do not have a standard requirements specification. In plan-driven projects the format is different, and it varies depending on the organization's processes and standards. There is no universal standard for requirements, although an IEEE standard for requirements documents exists and can be customized and adapted to suit the need and scale of the project. Agile projects do not need exhaustive documentation like a requirements document; plan-driven projects need a formal document, agreed upon and signed off, before development can take place.

The answer points at a real distinction between the two worlds: a user story ("As a warehouse manager, I want to see stock levels below reorder point so that I can reorder in time") is a compact, priority-ranked requirement written just before the increment is developed; a plan-driven requirements document is a formal, agreed, signed-off contract that development cannot start without. Both describe the same system's needs; they differ completely in form, timing, and legal weight.

Common pitfalls:

  1. Skipping validation because the requirements "look fine." Correctness, completeness, consistency, and realism are four separate checks — a document can be complete and still wrong, or consistent and still unrealistic. Skipping the checks moves the errors downstream, where each one costs a hundred times more.
  2. Writing only system requirements. Without the user-requirements level, the customer cannot review whether the system meets their needs, and the team loses the check against reality.
  3. Demanding one standard template for everything. There is no universal template: IEEE offers a standard that can be customized to the project's need and scale, agile projects write stories, and plan-driven projects write formal documents. The template must fit the process, not the other way around.
  4. Treating elicitation as a single interview. Requirements surface throughout the whole process; elicitation, specification, and validation are interleaved, and new requirements keep coming to light as the system is understood.

Recap: Requirements engineering has three interleaved activities — elicitation and analysis (gathering what the system must do, with models and prototypes), specification (translating it into user requirements, abstract statements for customers, and system requirements, detailed descriptions for developers), and validation (checking correctness, completeness, consistency, and realism). Agile projects replace the specification document with prioritized stories written just before each increment; plan-driven projects need a formal, signed-off document, for which the customizable IEEE standard exists but is not a universal template.

Bridge: Once the requirements exist, they must become a working system. The next section opens the second fundamental activity — development — with the design process: its inputs, its activities, and its outputs.

Real-world connection: Requirements failures are the most-cited cause of software project trouble — projects built for the wrong users, features nobody asked for, and budgets blown fixing misunderstandings. Every serious engineering domain has institutionalized the checks: regulated industries audit requirements documents, agile teams put a product owner in the room, and safety-critical work formally traces every requirement to a test. When you take on any software task, the elicitation questions ("who uses this, when, and what do they truly need?") are the most valuable questions you can ask.

2.7 Software Design and Implementation

Hook: A requirements document says what the system must do; code says how it does it. Between them sits a decision-heavy gap: which components, which data structures, which interfaces, which pieces to buy. Good design is what makes the jump from "what" to "how" survivable — and bad design is what makes it catastrophic.

2.7.1 The Design Process: Inputs, Activities, Outputs

Once the requirements are captured, analyzed, and specified, they have to be converted into an executable system. That is the development activity, and it involves the separate activities of software design and implementation. In most agile methods, design and implementation are interleaved, with no formal design documents produced; the software is still designed, but the design is recorded informally — on wikis, whiteboards, and notebooks.

Software design is a description of the structure of the software to be implemented: the data models and structures to be used by the system, the interfaces between the system components, and sometimes the algorithms to be used. Design is covered in detail in the course modules on software engineering.

Designers do not arrive at a finished design immediately; they develop the design in stages, adding detail as they go, with constant backtracking to modify earlier designs. The design process can be shown as an abstract model with inputs, process activities, and outputs. The design process activities are both interleaved and independent: even though they are shown as input, process, and output, they are interleaved as well as independent. New information about the design is constantly being generated, and this affects the various previous design decisions, so rework in design is inevitable. Design is an iterative process and a creative process.

The design process diagram (visualize it): three columns — on the left, the design inputs (platform information, software requirements, data descriptions); in the middle, the design activities (the four activities detailed below); on the right, the design outputs (the artifacts those activities produce). Arrows flow left-to-right, but the middle column's activities are drawn as interleaved and interdependent, not as a strict sequence. The one-sentence takeaway: the diagram looks like a pipeline but behaves like a web — a discovery in one activity routinely sends the team back to earlier decisions.

2.7.2 Platform and Data Inputs to Design

Most software interfaces with other software systems and other hardware systems: operating systems, databases, middleware, and other application systems. These make up the software platform — the environment in which the software will execute. Information about this platform is an essential input to the design process: what technology, what platform, what will the product run on? Designers must decide how to best integrate the system with its environment. If the system's data description is an essential input to the design process, it may be included in the platform specification, and the system data organization can be defined during design.

Think of the platform as the "ecosystem" the software will live in: the operating system it runs on, the database it stores its records in, the middleware that connects it to other services, and the neighboring application systems it must talk to. Ignoring the platform is designing in a vacuum — a system architected without knowing its database and OS will fight its environment from day one.

2.7.3 The Four Design Activities for Information Systems

The activities in the design process vary depending on the type of system being developed. Real-time systems, for example, require a further stage of timing design, but may not involve a database at all, so there is no database design. For an information system, the typical design process has four activities:

The four design activities for an information system:

  1. Architectural design — identify the overall structure of the system: the principal components, sometimes called subsystems or modules, their relationships, and how they are distributed. This is the skeleton: what the big pieces are and who talks to whom.
  2. Database design — design the system data structures and how these are to be represented in a database. The work here depends on whether an existing database is to be reused or a new database created — a decision that can change the whole shape of the data layer.
  3. Interface design — define the interfaces between the various system components. The interface specification must be clear and unambiguous. With a precise interface, a component may be used by other components without them having to know how it is implemented: each component is functionally independent, and components interact through the interface specification, as you learn in object-oriented design. Once the interface specifications are agreed — in terms of the parameters to be passed and received — the components can be independently designed and implemented, as long as the interface is clear, visible, and understood by the other components that interact with it. The interface is the contract that lets separate people build separate pieces in parallel.
  4. Component selection and design — look for reusable components, as in reuse-oriented development. If suitable components are found, they are integrated; if no suitable components are available, new software components are designed. The design at this stage may be a simple component description, with implementation details left to the programmer while the interface and algorithm are specified. If a reusable component is used, it may be a list of changes to be made to the reusable component. Alternatively, it may be a detailed design model expressed in UML (Unified Modeling Language) notation, which may then be used to generate an implementation from the model to the code.

The four activities are not a checklist to be finished one after another — they feed each other. The architecture constrains the database, the interfaces constrain the components, and what the component search finds (or fails to find) feeds back into the architecture.

2.7.4 Design Outputs

These activities lead from the design inputs — platform information, the requirements specification, and the data description — to the design outputs: the system architecture, the database design, the interface specification, and the component descriptions, which can then be used to implement the components.

The form of the outputs depends on the approach. For safety-critical systems, the outputs are detailed design documents setting out precise and accurate descriptions of the system. If a model-driven approach is used — converting UML models into code — the design outputs are the design diagrams. In agile methods, the outputs of the design process may not be a separate specification document like a design specification; they may be represented through the code of the program itself, which implements the required features and structure, with constant refactoring.

The same design work can produce very different artifacts: a 200-page design document for a safety-critical subsystem, a set of UML diagrams that generate code, or simply a well-structured codebase that has been continuously refactored. What matters is that the design exists — as a document, as diagrams, or as the code's own structure — and that it is accurate enough to build on.

2.7.5 Implementation and Programming Strategies

Developing the programs that implement the system naturally follows from the system design. Some classes of programs, like safety-critical systems, are designed in thorough detail and verified before any implementation begins. But typically in agile development methods, design and programming are interleaved. Software development tools can generate high-level skeleton code from a design, including code that defines and implements interfaces; in many cases the developer only needs to add the details of the algorithm of each program component.

Worked example — the IDE skeleton. If you have used IDEs, you have experienced this: the IDE generates the outline structure of the code, and you fill in the details.

  1. You ask the IDE to create a new class InvoiceService that implements the interface BillingService.
  2. The IDE generates the file: the class declaration, the implements clause, and empty method stubs for every method the interface demands — generateInvoice(...), listOutstanding(...), with the correct parameter lists and return types already written.
  3. The interface definitions are automatically consistent: because the stubs come from the same interface, there is no typo mismatch between what the interface promises and what the class provides.
  4. You fill in the algorithm bodies — the actual invoice computation, the queries, the validations — the part only a human can design.
  5. The IDE recompiles, and the code outline remains synchronized as you refactor the interfaces.

Sense-check: the tool did the mechanical, consistency-prone work (declarations, signatures, wiring), and the developer did the intellectual work (algorithms, data handling) — exactly the division of labor the design process intends, scaled down to a single file.

Programming is an individual activity, and there is no general process for programming. Different programmers proceed differently. Some start with the components they understand well, develop and test them first, then move on to the components that are less understood or less fully specified. Others take the opposite approach: they postpone the small familiar components (because they know how to develop and integrate them later), define the data early, understand the complex components, do some prototyping, and develop the less understood components first, using that to drive program development. Some like to define the data structures early; others defer the data to a later stage of the design process and look at the functionality first.

There is no single "right" programming strategy, only strategies that fit the individual and the problem. What the strategies share is that they are personal working styles — which is exactly why the process level (design, interfaces, architecture) exists: it coordinates individuals whose inner working methods cannot and should not be standardized.

2.7.6 Unit Testing and Debugging

Programmers normally carry out some testing of their code as they develop it. This is unit testing, and it often reveals program defects or bugs that must be removed from the program. Finding and removing bugs from the program is called debugging.

Testing and debugging are different activities. Testing establishes the presence of defects, while debugging locates and corrects them. When you debug, you generate hypotheses about the observable behavior of the program, and then test those hypotheses, hoping to find the fault that caused the output anomaly. Testing is covered in detail under the testing chapters. Testing a hypothesis may involve tracing the program code manually — walking through the code — and may require new test cases to identify and localize the problem. Interactive debugging tools, which show the intermediate values of the program variables and trace the execution of statements, are usually used to support the debugging process.

The distinction is easy to blur: testing is a yes/no verdict — "there is a defect somewhere"; debugging is an investigation — "here is exactly the fault, and here is the corrected code." Testing tells you the patient is sick; debugging is the diagnosis and the surgery. Real-world: most practitioners use a variety of debugging tools for their testing and debugging work.

Common pitfalls:

  1. Jumping to implementation without a design. In agile teams the design lives in the code itself, but it still exists. Skipping design entirely produces a system whose structure nobody can explain — and rework becomes the only strategy.
  2. Treating design as a one-pass activity. Rework in design is inevitable: new information constantly affects earlier decisions. The team that refuses to revisit the architecture because "the design is done" is the team that delivers the wrong system.
  3. Forgetting the platform. Design without knowing the operating system, database, middleware, and neighboring systems is designing in a vacuum — integration pain arrives on the first day of deployment.
  4. Confusing testing with debugging. Testing establishes that defects exist; debugging locates and corrects them. A team that "tests more" but never debugs systematically finds symptoms without ever fixing the disease.
  5. Leaving interfaces vague. If the interface specification is ambiguous, components cannot be built independently — every pair of components ends up needing its own coordination, and the parallel design the process promised never happens.

Recap: Development converts requirements into an executable system through design and implementation. Design is an iterative, creative process modeled as inputs (platform information, requirements specification, data description) → activities (architectural, database, interface, component selection and design) → outputs (system architecture, database design, interface specification, component descriptions); rework is inevitable. Programming is an individual activity with no general process, supported by tools that generate skeleton code and interfaces from designs. Unit testing and debugging are different: testing establishes the presence of defects, debugging locates and corrects them.

Exam note: Know the four design activities for information systems, the design inputs and outputs, and the testing-versus-debugging distinction (testing establishes the presence of defects; debugging locates and corrects them).

Bridge: The developers have built the system. Now the third fundamental activity takes over — validation. The next section shows how a system is tested in stages, from single components up to the customer's real data.

Real-world connection: Every serious codebase you will meet is a design artifact first: the architecture decides which team owns which module, the interfaces let teams develop in parallel, and the database design shapes everything from performance to migrations. The IDE habit you already have — letting the tool generate skeletons and filling in the algorithms — is the same division of labor used at industrial scale with UML model-driven development. And debugging with breakpoints and variable inspection, the daily craft of every practitioner, is the process this section describes: form hypotheses, test them, trace, localize, fix.

2.8 Verification and Validation: Software Testing

Hook: You have built the system; the requirements said it should do X, Y, and Z. How do you prove it does — and, more importantly, how do you find out that what the customer actually needed was W? That proof is the third fundamental activity: validation. And as with the rest of software engineering, the answer is not one big test, but a careful sequence of them.

2.8.1 What Validation Means

Of the four broad software development activities — specification, development, validation, and evolution — validation, or more generally verification and validation (V&V), is intended to show that the system both conforms to its requirements specification and meets the expectations of the system customer.

Program testing — executing the system using simulated test data — is the principal validation technique. Validation may also involve checking processes like inspections and reviews at each stage of the software process, from user requirements definition through design to program development. But most of the verification and validation time is spent on execution-based program testing.

The two halves of V&V answer two different questions. Verification asks "did we build the system right?" — does it conform to the requirements specification? Validation asks "did we build the right system?" — does it meet the customer's expectations? A system can pass verification perfectly and still fail validation, if the specification itself was wrong. Inspections and reviews (human reading of documents and code) catch problems the way a proofreader catches typos; program testing catches them the way a field trial catches flaws — by running the thing.

Except for small programs, systems should not be tested as a single monolithic unit after all components are assembled. Instead you use a three-stage testing process: system components are individually tested first, then the integrated system is tested, and then — for custom software — the customer tests the system with real customer data, which is acceptance testing. For products that are sold as applications, customer testing is sometimes called beta testing, where selected users try out and comment on the software.

Scope — why not one monolithic test? Testing everything at once fails for a simple reason: when the single big test fails, you cannot tell which component is at fault, or whether the fault is a component defect or an interaction between components. Stage-by-stage testing gives every failure a natural home — a component failure shows up in component testing, an interaction or interface failure shows up in system testing, and a requirements failure shows up in acceptance testing. For small programs the three-stage discipline can be relaxed; for anything larger, skipping the stages means paying the "needle in a haystack" price on every failure.

2.8.2 Three-Stage Testing: Component, System, Customer

Stage 1 — Component testing. The components that make up the system are tested by the people who are developing the system. Each component is tested independently, without other components. The components may be simple entities, like functions or object classes, or coherent groupings of these entities, like packages.

Worked example — automated component tests with JUnit. Test automation tools, like JUnit for Java, can rerun the tests when new versions of the components are created. Real-world: test automation tools are common in professional work environments.

Consider a component Invoice with a method totalWithTax(double amount) that applies an 8% tax. The developer writes a JUnit test the first day:

  1. Test case 1: totalWithTax(100.0) should return 108.0 (100.0 × 1.08).
  2. Test case 2: totalWithTax(0.0) should return 0.0 (a boundary check — no tax on an empty invoice).
  3. Test case 3: totalWithTax(-5.0) should throw an exception (invalid input must not silently produce -5.4).

Every day the developer runs the test suite, often automatically on every save. Now a change happens — the tax rate moves to 10% because of a new regulation. The method is changed, and the same three tests are rerun by the tool. Test case 1 fails (110.0 instead of 108.0) — the tool surfaces exactly which behavior changed, in milliseconds, without any human remembering to re-test. The tests are updated to the new expected values, and the suite turns green again.

Sense-check: the automation's value is regression detection — every new version of the component is checked against every old promise, automatically, forever.

Stage 2 — System testing. The components are integrated to create subsystems or systems, and the complete system is tested. This stage is concerned with finding errors that result from unanticipated interactions between components and from component interface problems. It is also concerned with showing that the system meets its functional and non-functional requirements. Non-functional requirements are emergent properties — like performance, reliability, usability, and maintainability — that only appear when the components work together. For large systems, system testing may be a multi-stage process: components are integrated to form subsystems, the subsystems are individually tested, and then the subsystems are integrated to form the final system.

Stage 3 — Acceptance (customer) testing. This is the final stage in the testing process, before the system is accepted for operational use. The system is tested by the system customer — or by a potential customer, in the case of a product — using real data rather than simulated test data. For custom-built software, acceptance testing may reveal various errors and omissions in the system requirements definition, because real data exercises the system in different ways from simulated test data. Customer testing may also reveal requirements problems — system facilities that do not really meet the real needs of the users, or unacceptable system performance. For products, customer testing (beta testing) shows how well the product meets customer needs.

Ideally, component defects are discovered early in the testing process and interface problems are found when the system is integrated. But as defects are discovered, the program must be debugged, and this may require the other stages of the testing process to be repeated — errors in program components may only come to light during system testing. So the process is iterative, with information fed back from later stages to earlier stages.

2.8.3 Testing in Incremental, Agile, and Plan-Driven Projects

Component testing is simply part of the normal development process, like unit testing. Programmers make up their own test data and incrementally test the code as it is being developed. Since the programmer knows the component well — its data structures and algorithms — he or she is best placed to generate test cases and test the components.

If you use an incremental approach, each increment should be tested as it is being developed, with the tests based on the requirements for that particular increment. If you use test-driven development (TDD), which is a normal part of the agile process, the tests are developed along with the requirements, before the development itself starts. This helps the testers and developers understand the requirements, and ensures there are no delays creating test cases — because when you specify a test case, you understand the functionality better.

In a plan-driven development process for embedded or critical systems, testing is driven by a set of plans: an independent team of testers works from test plans that have been developed from the system specification.

The contrast is worth keeping straight: in agile projects the same person who writes the code writes and runs the tests, increment by increment — TDD goes one step further and writes the test first, as a precise statement of the requirement. In plan-driven projects, testing is an independent discipline: a separate team of testers, working from formal test plans derived from the specification, with no stake in the code being tested. Both strategies test the same system; they differ in who tests, when, and against what.

2.8.4 The V Model

The link between testing and development activities can be drawn as the V model. Test plans are developed concurrently with the corresponding requirements and design specifications: you create the acceptance test plan as the requirements specification is done; as the system specification is developed, you have the system integration test plan; as the subsystems are designed, you have the subsystem integration plan; module coding and unit testing are done by the component developers. On the testing side you then run the subsystem integration test, the system integration test, and the user acceptance test, and finally the product is delivered and put into service. If you rotate the diagram of this model, you get a V shape — that is where the name comes from. Many colorful variants of the V model exist (searching images for "V model" shows them), and it is widely used in organizations.

The V model diagram (visualize it): draw a "V". Down the left arm, the development stages descend from requirements gathering through systems analysis and software design to module design, ending at the point of the V with coding. Up the right arm, the testing stages ascend: unit testing, integration testing, system testing, acceptance testing. Now draw horizontal dashed lines connecting each level — each development stage on the left has a matching testing stage on the right: requirements gathering pairs with acceptance testing, systems analysis pairs with system testing, software design pairs with integration testing, module design pairs with unit testing, and coding sits at the core. One student shared a V-shaped diagram of the plan-driven process showing exactly these correspondences — with the validation phase on one side and the verification phase on the other. The one-sentence takeaway: in a plan-driven process, every testing activity is planned at the same time as its corresponding development activity, so that the right test exists the moment the code is ready.

2.8.5 Beta Testing for Software Products

When a system is to be marketed as a software product, a testing process called beta testing is often used. Beta testing involves delivering the system to a number of potential customers who agree to use that system and report problems to the system developers. This exposes the product to real use and detects errors that the program developers may not have anticipated. After this feedback, the software product may be modified and released for further beta testing, or even released as a commercially available product.

Beta testing is acceptance testing with strangers: no customer contract, no hand-picked friendly users — just real users in real environments hammering the product with usage patterns the developers never imagined. The software may loop through several beta rounds (fix, release, collect more feedback) before the commercial release.

Common pitfalls:

  1. Testing everything as one monolithic unit. For anything but the smallest program, single-big-test validation makes every failure a mystery — component, interface, and requirements errors blur into one undiagnosable heap.
  2. Confusing the stages. Component testing finds defects in components; system testing finds interaction and interface problems; acceptance testing finds requirement errors with real data. Running the wrong stage's tests answers the wrong question.
  3. Skipping the test plans in plan-driven projects. An independent test team without formal test plans derived from the specification has nothing authoritative to test against — the tests drift into whatever the testers remember of the requirements.
  4. Forgetting that testing is iterative. Defects found in system testing often force earlier stages to be repeated; treating the stages as one-pass work hides the feedback loop the model depends on.
  5. Assuming passing tests mean the customer is happy. V&V shows the system conforms to the specification and meets expectations — but only acceptance/beta testing with real data exposes the requirement errors that simulated data never triggers.

Recap: Verification and validation show that the system conforms to its specification (verification) and meets customer expectations (validation), mostly through execution-based program testing. Testing runs in three stages — component (developers test units independently), system (integrated components, interaction and interface errors, non-functional emergent properties), and acceptance/customer testing (customer, real data). In agile projects each increment is tested as it is developed, with TDD writing tests before code; in plan-driven projects an independent team works from test plans. The V model pairs each development stage with its corresponding test stage, and beta testing opens products to real users before release.

Exam note: The three-stage testing process (component, system, acceptance/customer) and the V model correspondences (requirements gathering ↔ acceptance testing, systems analysis ↔ system testing, software design ↔ integration testing, module design ↔ unit testing) are flagged as core knowledge — be ready to reproduce the pairings.

Bridge: Testing is how the system is proven today. But the system's story does not end at delivery — the final fundamental activity takes over and runs for the rest of the system's life. The next section closes the session with software evolution.

Real-world connection: The three-stage discipline is everywhere in professional practice: developers run unit tests continuously (JUnit and its cousins in every language), CI/CD pipelines run integration suites on every commit, and release candidates face staged validation that mirrors the V model's pairings. Regulated industries make the correspondence literal — a requirements traceability matrix ties every requirement to a test, exactly as the V model's dashed lines suggest. And every app you have ever used went through beta rounds before you saw it.

2.9 Software Evolution

Hook: Open the app you used most in 2020. It still does roughly what it did then — but if you look closely, almost every part of it has been changed since: new features, redesigned screens, different payment flows, faster startup. Nobody "finished" that app; someone has been evolving it continuously, and that is normal. For most software, delivery is not the end of the story — it is the middle.

2.9.1 Evolution as a Continuum

Software undergoes change throughout its life, much like a human baby that, after delivery, grows and evolves through its whole life cycle. Software should continue to change, and so it should be maintainable.

Many people prefer development projects over maintenance projects: would you like to go on site for a maintenance project, where you have a huge code base developed decades ago that you cannot understand, and you have to support a system by going through the code, making modifications, and making it work in real time while it is in production? Evolution is a challenge, especially when there is no documentation and the code base is difficult to understand.

Q: How many of you prefer development over maintenance — fresh development from fresh requirements, rather than maintaining code that somebody else has developed? A: Whatever your preference, the distinction between development and maintenance is getting blurred, because very few software systems are completely new systems. It makes much more sense to see development and maintenance as a continuum of the entire life cycle — which is why specification, design, development, implementation, validation, and evolution are part of a continuous life cycle. It is more realistic to think of software engineering as an evolutionary process, where the software is continuously changed even during development, over its lifetime, in response to changing requirements and customer needs, because there are very rarely completely fresh projects to be developed from scratch. Real-world: most professional software work today means evolving an existing system, not building a brand-new one from nothing.

The point of the show-of-hands question is not to mock the maintenance-preferring minority — it is to dissolve the distinction. If almost no project starts from scratch, then "development" and "maintenance" are not two different careers; they are two phases of the same continuous activity. The evolutionary view of software engineering — the software is continuously changed even during development, over its lifetime, in response to changing requirements and customer needs — is the realistic description of the profession. The baby grows through its whole life cycle: delivery is birth, and the growing never stops.

2.9.2 The Evolution Process Model

The evolution process can itself be modeled as a cycle: you assess the existing system, propose system changes, modify the system, then check whether the modified system meets the requirements; the new system is assessed again, and the changes continue. This continuous cycle — assess, propose, modify, check, assess again — is why software evolution is never finished, and why the software must evolve to remain useful. Techniques like prototyping and incremental delivery help cope with this constant change.

The evolution cycle (visualize it): draw a circle with four boxes on it — assess existing system, propose system changes, modify system, check modified system — with arrows chasing each other around the loop. The cycle does not end: the checked system is assessed again, and the loop continues for the life of the software. The one-sentence takeaway: evolution is a closed loop, not a line — the same system is assessed, changed, and re-checked many times, and every round starts from the previous round's result.

Because the loop never stops, the process needs tools that tolerate change: prototyping (quick versions used to check requirements and design decisions before committing to them) and incremental delivery (delivering changes in slices so the system keeps working while it evolves) — both discussed in more depth in the agile session.

Common pitfalls:

  1. Believing "it's done" after delivery. Delivery is the start of the longest phase. The system will be changed constantly; if it was not built to be maintainable, every later change gets more expensive.
  2. Treating maintenance as unskilled work. Evolution work is often harder than greenfield development: you must understand a code base you did not write, often with no documentation, while the system is live in production and cannot simply be switched off.
  3. Ignoring the lifecycle in design. The iceberg from the waterfall section applies everywhere: the maintenance mass is below the waterline. Decisions made during design — readability, structure, documentation — decide how painful years of evolution will be.
  4. Expecting evolution to end. The assess–propose–modify–check loop has no exit. A team that treats a change request as "the last one" is fooling itself — the request stream is the system's normal metabolism.

Recap: Software changes throughout its life, like a human baby growing through its whole life cycle. Development and maintenance are not separate worlds but a continuum: very few systems are completely new, so most professional work means evolving existing systems. The evolution process runs as a continuous cycle — assess the existing system, propose changes, modify, check — never finished, which is why maintainability and change-friendly techniques (prototyping, incremental delivery) matter.

Exam note: The continuum claim is core: development and maintenance form a continuum because very few systems are completely new — know the assess–propose–modify–check evolution cycle and the human-baby analogy.

Bridge: This closes the tour of the four fundamental activities — specification, development, validation, and evolution. The two appendices that follow collect the session's exam guidance and industry applications into one place for revision.

Real-world connection: Look at the software that runs your university, your bank, or a hospital: most of it is between five and forty years old, and most IT budgets go to evolving it — new regulations, new interfaces, new business models — not to building replacements. The next time you read about a "legacy system," you are reading about the evolution phase at work. And the code you write for your coursework today is already a small experiment in evolution: the version you submit next week will not be the same file you wrote this week.

Exam Guidance Summary

No mark distribution or exam-format details were given in this session, but the teaching repeatedly emphasized a set of core points worth mastering:

  • The definition of a software process as a coherent set of activities for software production, and the four fundamental activities every process includes in some form: software specification, software development, software validation, and software evolution. Know what each one contains (Exam note: the four fundamental activities are core knowledge this session kept returning to).
  • Why there is no universal software process or process model, and what the choice depends on (customer, requirements, regulatory requirements, environment, type of software, skills, constraints). This theme was repeated throughout the session.
  • Plan-driven versus agile processes: plan-driven means planning all activities in advance and measuring progress against the plan; agile means incremental, iterative planning that continues as the software is developed.
  • The three general process models (waterfall, incremental development, reuse-oriented development), the situations each fits, and how large systems combine them.
  • The waterfall stages in order (requirements analysis and definition, system and software design, implementation and unit testing, integration and system testing, operation and maintenance), the sign-off principle, and feedback between stages in practice.
  • The consequences of prematurely freezing requirements, and of bypassing design problems with implementation tricks.
  • Incremental development: concurrent specification, development, and validation; how increments are chosen (most critical functionality first); its advantages and its management problems.
  • Concurrency versus parallelism: the correction that concurrency means activities interleaved in time while parallel means simultaneous. This is flagged as important knowledge in computing systems, especially for operating-system algorithms (Exam note: expect this distinction to matter — it was explicitly called important).
  • Requirements engineering activities: elicitation, specification (user versus system requirements), and validation (correctness, completeness, consistency, realism); how requirements work in agile (stories) versus plan-driven projects (formal document, IEEE standard exists but is customizable).
  • The design process: inputs (platform information, requirements specification, data description), activities (architectural, database, interface, component selection and design), and outputs (system architecture, database design, interface specification, component descriptions).
  • Testing versus debugging: testing establishes the presence of defects; debugging locates and corrects them.
  • The three-stage testing process (component, system, acceptance/customer testing), test-driven development, plan-driven test plans, and the V model correspondences (requirements gathering ↔ acceptance testing, systems analysis ↔ system testing, software design ↔ integration testing, module design ↔ unit testing).
  • Software evolution as a continuum of development and maintenance, and the assess–propose–modify–check cycle.

Study advice given during the session: review the difference between parallelism and concurrency on your own; note that there are many variants of the waterfall and V models, and search for examples; requirements engineering and design get detailed treatment in later sessions, and agile processes are covered in more detail in the next session.

The most reliable way to use this list: for each bullet, close your notes and explain the point aloud in two or three sentences — if you cannot, that is the gap to revise. The three ideas the session weighted most heavily are the four fundamental activities, the waterfall stages plus their feedback reality, and the concurrency-versus-parallelism distinction.

Key Industry Applications

  • Safety-critical systems — waterfall development with extensive analysis, verification, and documentation; formal verification for the most critical cases. Real-world: vehicle recalls of leading car brands after defective chips or software show how expensive safety problems become after implementation.
  • Embedded systems — software verified and then programmed into the ROM of the hardware, with no later changes possible.
  • Large systems engineering — systems of systems with many partnering companies and contractors; a common waterfall-style model plus complete specifications to distribute subsystem work.
  • Off-the-shelf products — always developed incrementally, and bought or configured rather than built from scratch.
  • Business systems — increasingly built by reusing and configuring existing systems; .NET and other application frameworks provide the reusable libraries and components.
  • The Rational Unified Process — a framework model adapted by large companies, notably IBM, though not widely adopted.
  • Requirements documentation — the IEEE standard for requirements documents, customized to project need and scale; agile teams write stories instead.
  • Testing practice — test automation tools such as JUnit for Java; test-driven development in agile teams; independent test teams working from test plans in plan-driven (embedded/critical) projects; beta testing for marketed software products; the V model widely used in organizations.
  • Design practice — UML (Unified Modeling Language) for detailed design models, model-driven generation of implementation from models, and IDEs generating skeleton code that developers fill in.
  • Maintenance and evolution — most professional work evolves existing, often decades-old code bases in production, which is why maintainability and refactoring matter.

The pattern behind the list: each application domain picks the process model that matches its risk profile. Where failure is catastrophic or hardware is inflexible, the waterfall's ceremony is the price of survival; where markets and requirements move fast, incremental development and reuse keep pace; and in the mature systems that dominate real IT estates, evolution and refactoring are the daily reality. When you meet a system in your career, ask which model built it — and which one should evolve it next.

SE Lecture 2 notes · Software Processes

Software Engineering· postgraduate· 2026-08-16

Sections Breakdown

12.1 What Is a Software Process?

What a software process is, its four fundamental activities, process descriptions, plan-driven versus agile, and process improvement.

22.2 Software Process Models

Process models as abstract representations, the three general models, matching the model to the system, and the Rational Unified Process.

32.3 The Waterfall Model

The waterfall model: its five stages, sign-off and feedback, renegotiating requirements, when it fits, and formal system development.

42.4 Incremental Development

Incremental development: concurrent specification, development and validation, choosing increments, advantages, problems, and refactoring.

52.5 Reuse-Oriented Development

Reuse-oriented development: building from existing components and reuse inside large systems.

62.6 Requirements Engineering Activities

Requirements engineering activities: elicitation and analysis, specification, validation, and agile versus plan-driven requirements.

72.7 Software Design and Implementation

Software design and implementation: design inputs, activities and outputs, programming strategies, and unit testing versus debugging.

82.8 Verification and Validation: Software Testing

Verification and validation: three-stage testing, testing in different process models, the V model, and beta testing.

92.9 Software Evolution

Software evolution as a continuum and the evolution process model.

10Exam Guidance Summary

The examinable core of the lecture grouped by topic.

11Key Industry Applications

Where each concept of the lecture shows up in real systems.

Postgraduate students in Software Engineering

Exam Revision Notes

Below is the distilled, exam-ready core. Every entry comes from the full explanation above. Use this section for rapid review; return to the main notes when a point needs more context.

What Is a Software Process?

Must-know: A software process is the set of related activities leading to a software system; every process includes specification, development, validation, and evolution; there is no universally applicable process.

⚠️ Top pitfall: Treating the four fundamental activities as a fixed sequence — in agile processes they are interleaved, not ordered.

Self-check: Name the four fundamental software engineering activities and give one sub-activity inside each.

Connects to: Sections 2.2, 2.3, 2.4 of this lecture

Software Process Models

Must-know: The three general process models — waterfall (sequential phases), incremental (interleaved activities across versions, basis of agile), reuse-oriented (configuring existing components) — and that no single model fits all software; large systems combine them.

⚠️ Top pitfall: Treating the models as mutually exclusive choices instead of combinable templates; judging a real process from its simplified diagram alone.

Self-check: Why does a process model provide only partial information about a process?

Connects to: Sections 2.1, 2.3, 2.4, 2.5 of this lecture

The Waterfall Model

Must-know: Waterfall stages in order (requirements analysis and definition; system and software design; implementation and unit testing; integration and system testing; operation and maintenance), sign-off principle, feedback between stages, and when the model fits (embedded, safety-critical, large systems).

⚠️ Top pitfall: Prematurely freezing requirements to avoid renegotiation delay — problems are left for later, the system may not do what users want, and design problems get circumvented by implementation tricks such as hard coding.

Self-check: Why is the real waterfall process never a simple linear sequence?

Connects to: Sections 2.1, 2.2, 2.4, 2.8 of this lecture

Incremental Development

Must-know: Incremental development interleaves specification, development, and validation; concurrent means interleaved in time while parallel means simultaneous; early increments carry the most critical functionality; advantages (cheaper changes, less rework, visible progress, early value) and problems (visibility, documentation decay, structural degradation) — refactoring counters degradation.

⚠️ Top pitfall: Confusing concurrency with parallelism: concurrent activities are interleaved in time (as in the incremental model), parallel activities run simultaneously.

Self-check: Why does the incremental model produce intermediate versions before a final version, and what is the difference between incremental development and incremental delivery?

Connects to: Sections 2.2, 2.3, 2.5 of this lecture

Reuse-Oriented Development

Must-know: Reuse-oriented development configures and integrates existing components (stand-alone applications, component packages, web services) instead of building from scratch; professional development rarely starts from zero; in large systems reuse combines with waterfall and incremental models.

⚠️ Top pitfall: Requirements compromises are inevitable with reuse — the assembled system may not exactly meet real user needs, and control over component evolution is lost to the component's owner.

Self-check: What are the three kinds of components most frequently reused, and what is the main trade-off of reuse?

Connects to: Sections 2.2, 2.4, 2.7 of this lecture

Requirements Engineering Activities

Must-know: The three requirements activities: elicitation and analysis (gathering needs, using models and prototypes), specification (user requirements = abstract statements; system requirements = detailed descriptions), and validation (correctness, completeness, consistency, realism); agile writes prioritized stories per increment, plan-driven needs a formal signed-off document.

⚠️ Top pitfall: Skipping requirements validation — errors found later in design or implementation are far more expensive than the same errors found in the requirements document.

Self-check: What are the four checks performed during requirements validation?

Connects to: Sections 2.1, 2.4, 2.7 of this lecture

Software Design and Implementation

Must-know: Design inputs (platform information, requirements specification, data description), the four design activities for information systems (architectural, database, interface, component selection and design), design outputs (system architecture, database design, interface specification, component descriptions), and the testing-versus-debugging distinction.

⚠️ Top pitfall: Confusing testing with debugging: testing establishes the presence of defects, while debugging locates and corrects them.

Self-check: Name the four design activities of an information system and the three design inputs.

Connects to: Sections 2.3, 2.5, 2.6, 2.8 of this lecture

Verification and Validation: Software Testing

Must-know: Three-stage testing (component, system, acceptance/customer) and the V model correspondences: requirements gathering ↔ acceptance testing, systems analysis ↔ system testing, software design ↔ integration testing, module design ↔ unit testing.

⚠️ Top pitfall: Testing the system as one monolithic unit — component, interface, and requirements errors then blur together and cannot be located.

Self-check: What are the three stages of testing, and which one uses real customer data?

Connects to: Sections 2.3, 2.4, 2.7 of this lecture

Software Evolution

Must-know: Development and maintenance form a continuum because very few software systems are completely new; evolution is an evolutionary process where software is continuously changed over its lifetime, following the assess–propose–modify–check cycle.

⚠️ Top pitfall: Treating delivery as the end and maintenance as unskilled work — evolution is the longest phase and most professional work means evolving existing systems.

Self-check: What are the four steps of the evolution process model, and why does the cycle never finish?

Connects to: Sections 2.1, 2.3, 2.4, 2.8 of this lecture

Exam Guidance Summary

Must-know: The four fundamental activities, the waterfall stages in order with sign-off and feedback, the concurrency-versus-parallelism distinction, and the V model correspondences are the most weighted items of this session.

⚠️ Top pitfall: Learning model names without their stage details — reproduce the waterfall stages, the V model pairings, and the four activities with their contents.

Self-check: Which session concepts are explicitly flagged as important for operating-system algorithms?

Connects to: Sections 2.1, 2.3, 2.4, 2.8 of this lecture

Key Industry Applications

Must-know: Each application domain picks the process model matching its risk profile: waterfall for safety-critical and embedded, incremental for products, reuse for business systems.

⚠️ Top pitfall: Remembering the model names without the domain mapping — know which model fits which industry context.

Self-check: Which process model fits safety-critical software, and which fits off-the-shelf products?

Connects to: Sections 2.3, 2.4, 2.5 of this lecture

Was this lecture useful?

Loading comments…
🤖

BitsNotes AI Assistant

Subject Notes Assistant

Configure AI Chat

Choose how to access the chatbot
Have your own API key?

Switch to "Bring Your Own Key" tab above for unlimited access with any OpenAI-compatible provider.

🔑 Enter API key above to fetch live models from provider, or enter model name manually.
OpenAI-Compatible API Support

Choose any provider preset (Gemini, DeepSeek, Kimi, GLM, MiniMax, Qwen, OpenAI, Groq, Ollama, etc.) or enter a custom endpoint URL.

Security & Privacy First

Your API key is sent directly from your browser to your specified provider. BitsNotes servers never store or see your key.