Why software needs a process at all
A program written by one student over a weekend needs no process. A system built by twenty people over two years, which a hospital will depend on, needs one — because the expensive mistakes are made long before any code is written.
The software development life cycle is the sequence of stages a project passes through. Different models arrange them differently, but the stages themselves are common to all of them.
| Stage | What happens | What goes wrong if skipped |
|---|---|---|
| Requirements | find out what is actually needed | you build the wrong thing perfectly |
| Analysis | work out what the system must do | requirements stay vague and untestable |
| Design | decide the structure before coding | the code grows unmanageable |
| Implementation | write the code | — |
| Testing | find the faults | the customer finds them instead |
| Deployment | put it into real use | it works only on the developer's machine |
| Maintenance | fix, adapt and improve | the system decays and is abandoned |
The cost of a fault multiplies at every stage
A misunderstood requirement caught during the requirements stage costs a conversation. Caught during testing, it costs rewriting the affected code. Caught after deployment, it costs an emergency release, retraining users and repairing whatever the fault did in the meantime. The estimates vary but the shape never does: the later a fault is found, the more it costs to fix, and that is the entire argument for the earlier stages.
Gathering requirements
This is the stage students find least interesting and the one that decides whether the project succeeds. The developer is rarely the person who will use the software, and what a user asks for is often not what they need.
The techniques are the same as in data gathering: interviews with the people who will use it, observation of how the work is done now, questionnaires for a large group, and examining existing documents such as the forms currently filled in by hand.
- Functional requirements — what the system must do. "The system shall calculate each student's attendance percentage."
- Non-functional requirements — how well it must do it. Speed, reliability, security, usability. "The report shall be produced within five seconds."
- Requirements must be testable. "The system should be fast" cannot be checked; "each page loads within two seconds" can.
- They must be agreed in writing, or the argument about what was promised happens after the work is done.
Watch what people do, not only what they say
Ask a clerk how they process an application and you get the official procedure. Watch them and you find the sticky note listing the four exceptions, and the second spreadsheet nobody mentioned. Observation catches the parts of the job people have stopped noticing they do — and those are exactly the parts a new system breaks.
Waterfall and iterative models
The waterfall model runs the stages strictly in order: each is completed and signed off before the next begins. It is simple to manage and produces thorough documentation, and it works when the requirements genuinely are known in advance and will not change — a system replacing a well-understood manual process, or one with legal requirements fixed by statute.
Its weakness is that the customer sees nothing working until the end. If the requirements were misunderstood, that becomes apparent at the point where change is most expensive.
Iterative and agile models instead build a small working version, show it to the customer, and repeat. Each cycle produces something usable, so misunderstandings surface within weeks. The cost is less predictability about the final scope and lighter documentation, which some projects cannot accept.
| Waterfall | Iterative / agile | |
|---|---|---|
| Order of stages | strictly sequential | repeated in short cycles |
| Customer sees working software | at the end | every cycle |
| Handles changing requirements | badly | well |
| Documentation | extensive | lighter |
| Suits | stable, well-understood requirements | uncertain or evolving requirements |
Testing, and what "tested" means
Testing does not prove software correct — it finds faults. A program can pass every test and still contain one, which is why the choice of tests matters more than their number.
Test at several levels. Unit testing checks one function in isolation. Integration testing checks that units work together, which is where most faults actually appear. System testing checks the whole thing against the requirements. Acceptance testing is done by the customer, who decides whether it does what they asked for.
For each test, choose data deliberately: normal values, boundary values at the edges of what is allowed, and erroneous values that must be rejected cleanly rather than crashing.
A field accepts a student's age, which must be between 11 and 19. Give suitable test data and explain each choice.
- Normal: 15. Should be accepted.Confirms the ordinary case works before testing anything clever.
- Boundary: 11 and 19. Both should be accepted.The limits themselves are inside the allowed range, and off-by-one errors show up here.
- Boundary: 10 and 20. Both should be rejected.The values just outside catch a condition written with > instead of >=.
- Erroneous: "fifteen", −5, and an empty field.Each must produce a clear message rather than a crash. An empty field is the one most often forgotten.
Normal 15; boundary 11, 19, 10, 20; erroneous text, negative and empty.
Before you leave this chapter
- Requirements, analysis, design, implementation, testing, deployment, maintenance.
- The later a fault is found, the more it costs — which is the argument for the early stages.
- Functional = what it does; non-functional = how well. Both must be testable.
- Waterfall suits stable requirements; iterative suits uncertain ones.
- Testing finds faults, it does not prove correctness. Test normal, boundary and erroneous data.
What "fix it early" actually costs
Every argument for spending time on requirements and design rests on one claim: a fault gets more expensive the longer it survives. It is worth seeing the shape of that, because the growth is not gradual.
Move the slider to After release. The same misunderstanding now costs roughly a hundred times the conversation that would have prevented it — and that multiplier is the entire justification for the stages before coding.
Why the last step is so much worse
After release the repair is not just a code change. The fault must be diagnosed from a user's description rather than a test result, an emergency release must be prepared and distributed, users retrained, and any data the fault corrupted repaired. Each of those is work that simply does not exist when the same mistake is caught in a design meeting.