Design in the software engineering context
◈ 5 cardsWhere design sits in the process, which requirements-model element feeds which design action, the three marks of a good design representation, and FURPS.
Design is the hinge between what and how
Software design is the last engineering action inside the modelling activity. It begins once requirements have been analysed and modelled, and it ends when there is a blueprint detailed enough to construct from. It happens whatever process model you are running — a waterfall project reaches it once, an incremental project reaches it every increment, an agile team reaches it several times a week — because "turn what the stakeholders asked for into a structure somebody can build" is work that has to happen somewhere. Naming it as its own action does not commit you to a heavyweight document; it commits you to doing the thinking deliberately rather than discovering the structure by accident, halfway through coding.
The reason to insist on that is quality. Design is the only point in the process where you can inspect the shape of the system before anyone has paid to build it. There is no executable yet, so you cannot test; what you can do is review a representation. A design that is never separately represented is a design nobody can review, and a system whose structure exists only in its source code is one whose structural mistakes surface at integration — late, when the budget is spent and the schedule has no slack left.
Every design element is fed by an analysis element
The requirements model does not sit politely beside the design model. It is consumed by it. Four design actions each draw on named analysis work products:
- Data/class design turns analysis classes, their attributes and their CRC responsibilities into design class realisations and the data structures behind them.
- Architectural design turns analysis packages and class relationships into the major structural elements, the architectural style, and the constraints that hold them together.
- Interface design turns usage scenarios and behavioural models into the flows across each boundary — the user's, the external systems', and the internal ones between components.
- Component-level design turns class-based and behavioural detail into a procedural description of each component: its algorithms, its local data, its interface.
The thinking move is traceability run backwards. Point at any line of the design and ask which requirement put it there. If the answer is "none", you have either invented a requirement nobody asked for or you are looking at a piece of accidental structure that will cost you at maintenance time.
Judging a design before it runs
Three characteristics separate a good design representation from a bad one. It implements every explicit requirement and accommodates the implicit ones stakeholders never bothered to write down. It is readable — a usable guide for the people who will code, test and later support the software, not a private notation. And it gives a complete picture across the data, functional and behavioural domains, from an implementation point of view.
Those are goals, not tests. The instrument that actually checks them is the technical review: a short meeting, usually two to four people, with a leader who runs it, a recorder who writes down every problem raised, and the producer whose work product is on the table. Reviewers read the design beforehand hunting for errors, omissions and ambiguity; the meeting exists to note problems, not to solve them. Design quality is also named as attributes, most commonly through FURPS — functionality, usability, reliability, performance, supportability — Robert Grady's shorthand from Hewlett-Packard. Its value at a review is the last letter: supportability is the question a purely functional walkthrough never thinks to ask.
Worked example — BorrowBox at the moment analysis stops
BorrowBox lets a member reserve a power tool in an app, collect it from a smart locker with a one-time QR token, and return it to any locker for a librarian to inspect and re-shelve. Suppose analysis has finished: there is a class model (Member, Reservation, Tool, ToolCopy, Locker, DamageReport, LateFee), a set of use cases, and a state model for a tool's life. Design now asks of each of those artefacts: what does it become?
Reservation's attributes and its CRC responsibilities become a design class with a chosen internal structure and an explicit hold-expiry rule — that is data/class design. The observation that the locker estate is an external, occasionally offline fleet of devices becomes a structural decision: publish to an event channel rather than call the lockers synchronously — architectural design. The use case "Collect a reserved tool" becomes both the scan screen's interaction flow and the message contract with the locker vendor — interface design. And the guard "the hold expires two hours after the reservation window opens" becomes an algorithm with local data inside one component — component-level design. Four design actions, one requirements model, and each of them traceable back to something a stakeholder actually said.