RTS questionnaire · Q42 · Low-Level Design proof

Have you been involved in Low-Level Design (LLD)?

The five parts of a low-level design as the answer describes them, worked through on one feature: classes with one responsibility each, the error paths drawn before coding, the data design the code will inherit, the contracts, and the review that happens before the first commit.

Status: reviewed Live LLD workflow Classes · Behaviour · Data · Contracts · Review Jump to live proof ↓

42. Low-Level Design (LLD)

Answer as submitted

“Yes — LLD is where I spend a large part of my design effort, because it decides whether an implementation is clean and maintainable.”
Technical decision: expand. The submitted line claims the involvement. This page is the separate, detailed version: it works one feature from the design review to the artefacts it produced, and it shows the parts of LLD that are usually skipped — the sequence diagram for each error path, the transaction boundary drawn on the diagram, the open questions with an owner, and the pseudocode for the algorithm that is hard to get right.

Expanded answer

Yes, and LLD is where the maintainability of a system is actually decided, long before architecture diagrams are drawn. Class and component design: one responsibility per class, stated in a sentence a reviewer can disagree with, dependencies pointing inward through ports the calling layer owns, names taken from the ubiquitous language rather than from the ORM, and design patterns applied where they resolve a named force — a strategy because the rule varies, a decorator because the behaviour is cross-cutting — instead of because a catalogue exists. When a responsibility needs the word “and” to describe it, that is the design pointing out which two classes it wants to become. Behavioural design: a sequence diagram for the main flow and one for each way it can fail, a lifecycle expressed as an explicit state machine with the legal transitions named, the transaction boundary drawn on the diagram rather than discovered in the code, and the concurrency and idempotency rules stated in terms of what the database enforces. The error paths are the whole point, because that is where the ambiguity lives and where the implementer would otherwise have to guess. Data design: tables with the constraints that enforce the invariants, keys chosen for stability, the indexes derived from the queries the feature will actually run, a forward-only migration that applies while the previous version is still serving traffic, and an explicit mapping that keeps the persistence model, the domain object and the wire DTO from being conflated. Contract design: every endpoint designed before it is written, including which status code each failure returns, which validation rules belong at the edge and which in the domain, and how pagination behaves on the first and last page — plus versioned event schemas and the failure mode and timeout of every external integration. Deliverables and review: a design document a reviewer can disagree with, pseudocode for the algorithms that are hard to get right, testability notes written before the tests exist, and a design review before coding — after which the design evolves where the code does, in pull requests, rather than stopping at the first commit.

Part of the LLDThe deliverableThe ambiguity it removes
Class and component designa responsibility sentence per class, ports, dependency directionwho owns the rule, and which way the dependencies point
Behavioural designa sequence per flow including each error path, a state machine, the transaction boundarywhat happens when it fails, and where the transaction opens and commits
Data designconstraints, keys, the indexes with their queries, the migration plan, the three mappingswhether an invariant lives in the schema or in code, and how the change ships without downtime
Contract designevery endpoint with all of its statuses, versioned event schemas, external integrations with failure modeswhat the implementer does for each rejection, and what happens when a dependency is unavailable
Deliverables and reviewthe design document, pseudocode for the hard parts, testability notes, the review before codingwhether the design is agreed before it is expensive to change
Open questionseach with an owner and a datedecisions being made by whoever types first

Live low-level design workflow proof

The running component below changes its part-of-the-design/result view through real event binding. Select a part to see the deliverable, the reasoning behind it, and the evidence that the detail is actually there.

LIVE PREVIEW
RUNNING
LOW-LEVEL DESIGN WORKFLOWRUNNING

Choose a part of the low-level design

Select a part to inspect the deliverable, the reasoning and the evidence.

$ one responsibility per class · ports and dependency direction · ubiquitous-language naming · patterns applied where they resolve a named force

Each class gets a responsibility that can be stated in a sentence a reviewer is able to disagree with, and the dependencies point inward through ports the calling layer owns. Patterns are applied where they resolve a named force — a strategy because the rule varies, a decorator because the behaviour is cross-cutting — rather than because a catalogue exists. When a responsibility needs the word "and" to describe it, that is the design pointing out which two classes it wants to become.

classes whose responsibility needs an "and" to state: 0
ports owned by the calling layer: all
patterns applied without a named force: 0
names taken from the ubiquitous language rather than from the ORM: all
ports a unit test needs to stand in for: 3, with no database involved

What good LLD buys

Rules I apply. Write the responsibility of each class as a sentence somebody can argue with, because a responsibility nobody can dispute is a responsibility nobody has examined; draw a sequence diagram for every error path and not only for the happy one, since the main flow is the part everyone already agrees on; model any lifecycle as an explicit state machine so illegal transitions are refused in one place instead of half-checked in five; mark the transaction boundary on the diagram, because discovering it in code means discovering it after the first production incident; give every invariant that the schema can enforce to the schema, since that is the only check that survives concurrency; name the index with the query it serves, or it is a write cost with no reader; state the idempotency rule per operation rather than per system; write the pseudocode for the algorithm that is hard to get right, because the tie-break and the retry are where the defects live; and list the open questions with an owner and a date, so a decision cannot be made by whoever types first.
Boundary for Q42: this page covers the low-level design and its artefacts. The pattern catalogue and SOLID in their own right are on the Q33 proof page; the API contract as a lifecycle is on Q49; the database design in depth is on Q47; and the design artefact types the next question mentions — ER diagrams, schemas, contracts, component and workflow design — are the subject of Q43.

Source files

Select a file to inspect the proof with syntax highlighting and line numbers. The first file is the code running the component above; the others are the design document itself with its error paths and open questions, the lifecycle as an executable state machine, and the pseudocode for the allocation algorithm with its invariants stated first.

Acceptance criteria