Delivery framework for LLD
Five phases and a bonus round for taking a low level design from a blank page to working classes, with a tic-tac-toe example worked through end to end.
Run a low level design question in five phases: requirements, entities and flows, interfaces, implementation, walkthrough, then extensibility as a sixth. Each phase feeds the next, so you are never inventing structure on the spot.
The phases
| # | Phase | You leave with |
|---|---|---|
| 1 | Requirements | Scope, constraints, assumptions, what is out |
| 2 | Entities and flows | The nouns, their attributes, who owns whom, the use cases |
| 3 | Interfaces | Class names, signatures, responsibilities. No bodies |
| 4 | Implementation | Bodies for the methods that matter |
| 5 | Walkthrough | One flow traced through the code you just wrote |
| 6 | Extensibility | Where a new requirement plugs in |


Phase 6 is the one to drop when the work has to stop somewhere. The other five are the design itself.
The example below is tic-tac-toe, small enough that the rules need no explaining.
Phase 1: Requirements
Ask until you can write the spec down and have whoever owns the problem agree with it. Four things to pin: what it must do, what the rules are, what happens when someone breaks a rule, and what you are not building.
For tic-tac-toe:
- Two players alternate on a 3x3 board, X goes first.
- A player wins with three of their symbol in a row, column, or diagonal.
- A full board with no winner is a draw.
- Playing on a taken cell, or playing once the game is over, is rejected, and the turn does not pass.
- Out of scope: persistence, networking, AI opponent, more than two players.
Say the out of scope list out loud, otherwise the question grows while you are answering it.
Phase 2: Entities and flows
Pull the nouns out of the spec, give each one attributes and a single responsibility, then say how they connect. Do the flows in the same breath: narrate a use case and the missing entities show up on their own.
Entities:
Boardholds a grid of cells and knows what is at each position.Playerhas a symbol, X or O.Gameowns the board and the two players, and tracks whose turn it is.
Relationships: one game owns one board and exactly two players. The board owns its cells. Nothing points back upward, so there are no cycles to reason about.
Flows: start a game, take a turn, reject an invalid turn, end on a win, end on a draw.
Keep the ownership direction explicit. The usual mistake here is a child holding a reference back to its parent for no reason.
Phase 3: Interfaces
Turn entities into classes. For each one, decide state and behaviour, and write the signatures. No method bodies yet: this phase is about what each class promises, and bodies hide that behind detail.
Work top down from the class that orchestrates, here Game. Its method list tells
you what everything below it has to provide.
WinStrategy is an interface rather than a method on Board because the win rule is
the part most likely to change. That is a guess about the future, so justify it in one
sentence and move on.


Phase 4: Implementation
Fill in the methods that carry the logic. Skip getters. Happy path first, then the rejections.
Both guards run before the turn advances, so a rejected move leaves the same player on turn. That was a requirement from phase 1.
Leaving a body as a comment is fine when the logic is a loop anyone can picture. Spend the time on the methods where a reviewer would disagree with you.
Phase 5: Walkthrough
Take a flow from phase 2 and run it through the code. This catches the errors that reading cannot.
X plays (0,0). Status is in progress, cell is empty, X is placed. No win, board is not
full, turn passes to O. O plays (1,1), same path. X plays (0,1), then O plays (2,2),
then X plays (0,2). hasWon finds X across the top row, status becomes WON, and the
turn never advances, so the board freezes with X as the winner.
Then try to break it. O calls play(0,0) after the win and the first guard throws.
Phase 6: Extensibility
Take a requirement that was out of scope and show where it lands. If the answer is a new class, or a different implementation of an existing interface, the design held.
- 4x4 board:
new Board(4). Board was never hardcoded to 3. - Connect four style, four in a row:
new LineWinStrategy(4). Game does not change. - A bot player: make
Playeran interface with anextMovemethod, add a second implementation. Game still calls the same thing. - Undo:
Gamekeeps a stack of moves,Boardgains aclear(row, col). This one touches existing classes, so say so rather than pretending it is free.
Undo is the useful one to raise. Saying which change does not fit cleanly is worth more than claiming every change is a one liner.
What usually goes wrong
People rush phase 3 because writing signatures feels slower than writing code. It is the phase worth the most of your attention.
The other common miss is phase 5. A short trace catches mistakes that rereading the code will not.