How to approach OOD interviews
A step-by-step framework for object-oriented design interviews, from clarifying requirements to implementing clean, extensible code in 45 minutes.
You just heard "Design a parking lot system" and your mind went blank. Not because you don't know what a parking lot is, but because you don't know where to start. Do you draw a class diagram? Write code? Ask questions? All three at once?
Most candidates fail OOD interviews not because they lack design knowledge, but because they lack a repeatable process. They jump straight into code, forget to ask clarifying questions, or spend 30 minutes modeling entities and run out of time before writing a single line. The fix isn't more pattern memorization. It's a framework you can apply to any problem in any 45-minute window.
This guide gives you that framework. Five steps, predictable time splits, and a clear signal at each stage of what good looks like.
What interviewers actually evaluate
Before learning the framework, understand what's being scored. OOD interviews test five dimensions, and most candidates only prepare for one of them (writing code).
| Dimension | What they're watching for | Common failure mode |
|---|---|---|
| Requirements gathering | Do you ask clarifying questions before designing? | Jumping straight into code without confirming scope |
| Entity modeling | Can you identify the right nouns and their relationships? | Missing key entities or creating unnecessary ones |
| Pattern selection | Do you pick patterns that solve real forces, not just patterns you memorized? | Using Strategy for everything, or naming patterns without justifying them |
| Code quality | Is the code clean, extensible, and testable? | Giant classes, public fields, no interfaces |
| Trade-off discussion | Can you articulate why you chose X over Y? | "I always use this pattern" with no rationale |
I've seen candidates write flawless code and still get rejected because they never asked a single question. I've also seen candidates with mediocre code get strong-hire signals because they talked through trade-offs with clarity. The code matters, but it's maybe 40% of the evaluation. The other 60% is how you think.
The one thing interviewers remember
Interviewers write feedback immediately after the session. They remember how you made decisions more than the code you wrote. "Candidate identified the core trade-off between flexibility and simplicity and chose appropriately" is a strong-hire signal.
The 5-step framework
Here is the process I recommend for every OOD interview, regardless of the problem.
Each step has a specific output. You're not done with a step until that output is on the whiteboard (or in the shared doc).
| Step | Duration | Output |
|---|---|---|
| 1. Clarify requirements | ~5 min | Bulleted list of functional/non-functional requirements |
| 2. Identify entities | ~5 min | List of 4-8 core classes with key attributes |
| 3. Define relationships | ~5 min | Class diagram showing associations, inheritance, composition |
| 4. Choose patterns | ~10 min | Named patterns anchored to specific forces |
| 5. Implement and trace | ~20 min | Working code + walkthrough of one scenario |
Step 1: Clarify requirements
Never start designing before you know what you're designing. The interviewer gave you a vague prompt on purpose. They want to see you narrow it down.
Ask three categories of questions:
Scope: "Should I focus on the core booking flow, or also handle payments and cancellations?" This tells the interviewer you understand that 45 minutes has a budget and you're spending it wisely.
Actors: "Who are the users of this system? Just customers, or also admins and operators?" Every actor becomes a potential class or interface.
Constraints: "Should I handle concurrency? Multi-floor support? Different vehicle types?" These constraints directly influence which patterns you'll need.
My recommendation: spend exactly 3-5 minutes here. Ask 5-7 questions. Write the answers as bullets on the whiteboard. The interviewer will often reveal hidden requirements during this phase that completely change the design.
The silent interviewer trap
Some interviewers deliberately stay quiet when you ask questions, answering with "It's up to you." This is not a signal to stop asking. It means they want you to make and state your own assumptions. Say: "I'll assume X, Y, Z. I can revisit if needed."
Step 2: Identify entities
Now turn the requirements into nouns. A parking lot system might give you: ParkingLot, Floor, Spot, Vehicle, Ticket, Payment. An elevator system: Elevator, Floor, Request, Scheduler.
Three rules for entity identification:
- Start with the core domain objects. What are the physical or logical things in this system? A parking spot, a vehicle, a ticket.
- Look for actors. Who interacts with the system? An attendant, a customer, an admin. Not all actors become classes, but many do.
- Identify the orchestrator. There's almost always a service or manager that coordinates the workflow.
ParkingLotService,ElevatorScheduler,OrderProcessor.
Don't overmodel at this stage. You need 4-8 entities, not 20. If you're listing more than 10 classes before writing any code, you're over-engineering. Drop anything that doesn't directly serve a core use case.
For each entity, jot down 2-4 key attributes. Not every field, just the ones that drive behavior. A ParkingSpot needs spotType, isOccupied, and spotNumber. It does not need createdAt or lastModified at this stage.
Step 3: Define relationships
This is where most candidates either skip entirely or get wrong. Relationships are the skeleton of your design. Get them right and the code practically writes itself.
For each pair of entities, ask:
- IS-A or HAS-A? Is a
Cara type ofVehicle(inheritance)? Or does aParkingLothave manyFloorobjects (composition)? - Multiplicity? Does one
Floorhave manySpotobjects? Does oneTicketreference exactly oneVehicle? - Dependency direction? Does
ParkingLotServicedepend onSpotAssignmentStrategy, or the other way around? Get this wrong and your code becomes untestable.
Draw a quick class diagram on the whiteboard. It doesn't need to be UML-perfect. Boxes with names, lines with labels. The interviewer wants to see that you think in terms of structure, not just procedural code.
The biggest mistake here: making everything inherit from everything. Prefer composition over inheritance. If you're drawing more than two levels of inheritance hierarchy, stop and reconsider. Most OOD problems need one interface hierarchy and lots of composition.
Step 4: Choose patterns
This is the step that separates candidates who memorized patterns from candidates who understand them. Don't pick a pattern because you know it. Pick it because a specific force in your design demands it.
The conversation should sound like:
"We have multiple vehicle types that need different spot sizes. This is a classic case where the assignment logic varies by type, so I'll use the Strategy pattern for spot assignment. This way we can add new vehicle types without modifying the core parking logic."
Not:
"I'll use the Strategy pattern here because it's a good pattern."
Three patterns cover 80% of OOD interview problems:
| Pattern | Use when... | Example |
|---|---|---|
| Strategy | Behavior varies by type or configuration | Pricing algorithms, assignment rules, notification channels |
| State | An object has a lifecycle with distinct phases | Order states, elevator states, game turns |
| Observer | Multiple components react to a single event | Notifications, analytics, audit logging |
For your interview: name the pattern, state the force it addresses, and explain how it makes the design extensible. One sentence each. Then move to code.
Pattern justification formula
"We need [capability]. Without a pattern, we'd have [problem: if/else chain, tight coupling, etc.]. [Pattern name] solves this by [mechanism]. This means we can [extension point] without modifying [existing code]."
Step 5: Implement and trace
Now write code. But don't try to implement everything. Pick the 3-5 most important classes and write them fully. For the rest, declare the interface and move on.
Priorities when coding:
- Interfaces and abstractions first. Write
SpotAssignmentStrategybeforeNearestSpotStrategy. - One concrete implementation. Prove the pattern works with one real subclass.
- The orchestrator. The service class that wires everything together.
- Skip boilerplate. Don't write getters, setters, equals, hashCode. Say "I'd generate these" and move on.
After writing the code, trace one complete scenario verbally: "A motorcycle arrives. The attendant calls parkVehicle(). The service checks assignSpot() using the motorcycle strategy, which finds the smallest available spot. A ticket is created, the spot is marked occupied, and the ticket is returned." This trace proves your design actually works end-to-end.
Step-by-step walkthrough: parking lot
Let me walk through the framework with a compressed parking lot example to show what the output looks like at each step.
Step 1 output (requirements):
- Multi-floor parking lot with different spot sizes (compact, regular, large)
- Support multiple vehicle types (motorcycle, car, truck)
- Assign the nearest available spot that fits the vehicle
- Issue tickets on entry, accept payment on exit
- Track occupancy per floor
Step 2 output (entities):
ParkingLot,Floor,ParkingSpot,Vehicle(with subtypes),Ticket,Payment
Step 3 output (relationships):
ParkingLotHAS manyFloor(composition)FloorHAS manyParkingSpot(composition)VehicleIS-A hierarchy:Motorcycle,Car,TruckTicketreferences oneVehicleand oneParkingSpot
Step 4 output (patterns):
- Strategy for spot assignment (different algorithms: nearest, most-compact, load-balanced)
- Enum for spot types and vehicle types (type-safe, no magic strings)
- Observer for occupancy tracking (floor dashboard updates when spots change)
Step 5: Here's what the core code looks like. Not every class, just the ones that matter.
public class ParkingSpot {
private final String spotId;
private final SpotType type;
private final int floor;
private Vehicle currentVehicle;
public ParkingSpot(String spotId, SpotType type, int floor) {
this.spotId = spotId;
this.type = type;
this.floor = floor;
}
public boolean isAvailable() { return currentVehicle == null; }
public boolean canFit(Vehicle vehicle) {
return isAvailable() && type.fits(vehicle.getType());
}
public void occupy(Vehicle vehicle) {
if (!canFit(vehicle)) {
throw new IllegalStateException("Spot cannot fit this vehicle");
}
this.currentVehicle = vehicle;
}
public void release() { this.currentVehicle = null; }
// Getters omitted for brevity
public String getSpotId() { return spotId; }
public SpotType getType() { return type; }
public int getFloor() { return floor; }
}Notice what's not here: no ParkingLot class wrapping everything, no Floor class (the spot already has a floor number), no payment calculation logic. In a 45-minute interview, you implement the core and mention the rest verbally: "Payment calculation would use another Strategy, and I'd add an Observer for the floor occupancy dashboard."
Time management: how to spend 45 minutes
Time kills more OOD candidates than lack of knowledge. Here's the split I recommend:
| Phase | Minutes | What to produce | Danger sign |
|---|---|---|---|
| Clarify requirements | 0-5 | 5-7 bullet points confirmed with interviewer | Still asking questions at minute 8 |
| Entities and relationships | 5-15 | Class diagram with 4-8 entities and labeled edges | Drawing 15+ classes |
| Choose patterns | 15-25 | 2-3 named patterns with justifications | Naming 5+ patterns without justification |
| Implement code | 25-40 | 3-5 core classes, runnable logic | Writing boilerplate getters for 10 minutes |
| Trace and discuss | 40-45 | End-to-end scenario walkthrough, extensions | Silence, or still writing code |
Three rules for staying on track:
Set verbal checkpoints. At the 15-minute mark, say out loud: "I've identified the core entities and relationships. Now I'll pick patterns before coding." This signals structure to the interviewer and keeps you honest about pacing.
Skip boilerplate aggressively. Don't write constructors, getters, equals, toString. Say "I'll assume standard boilerplate" and spend that time on real logic. The interviewer is evaluating your design decisions, not your ability to type public String getName() { return name; }.
Code the happy path first. Get one scenario working end-to-end. Then, if time permits, discuss error handling, concurrency, and edge cases verbally. A working happy path with spoken edge cases beats half-implemented error handling every time.
What separates junior from senior
The same design problem, three different experience levels. Here's what changes:
| Dimension | Junior (L3-L4) | Mid (L4-L5) | Senior (L5-L6) |
|---|---|---|---|
| Requirements | Starts coding immediately | Asks 2-3 questions | Runs a structured requirements mini-interview, states own assumptions |
| Entities | One or two god classes | Reasonable split, but some anemic models | Clean domain model with behavior in the right places |
| Relationships | Everything is public, no clear dependencies | Uses composition, some inheritance | Dependency inversion, interface-first, testable structure |
| Patterns | None named, or uses "design pattern" as a buzzword | Names Strategy or Observer, may not justify it | Names patterns, states the force, explains the alternative they rejected |
| Code quality | Long methods, public fields, no validation | Clean-ish code, some defensive checks | Small focused methods, immutable where possible, clear error messages |
| Trade-offs | "This is how I always do it" | "We could also use X" (if prompted) | "I chose X over Y because Z. If the requirements changed to W, I'd switch to Y." |
| Time management | Runs out of time mid-code | Finishes code, no time for discussion | Finishes with 5 minutes for walkthrough and extensions |
The single biggest separator: proactive trade-off discussion. A senior candidate says "I'm choosing composition over inheritance here because the vehicle types might overlap in the future, and inheritance would force a rigid hierarchy." A junior candidate just writes the inheritance tree without comment.
Common pitfalls
1. Skipping requirements entirely
Jumping straight to code tells the interviewer you don't think before you build. Even if your design is perfect, you've demonstrated that you'd do the same thing in a real project: build first, ask questions later. Spend five minutes asking questions. It's the cheapest investment with the highest return.
2. Over-modeling
You don't need a class for every noun in the problem statement. A parking lot doesn't need a ParkingLotConfiguration, SpotFactory, VehicleRegistry, FloorManager, and SpotValidator. Start with the minimum viable set of entities. If the interviewer wants more depth, they'll ask.
3. Pattern name-dropping without justification
Saying "I'll use the Factory pattern here" without explaining why is worse than not naming the pattern at all. It signals that you memorized a list but don't understand the forces. Always connect the pattern to a specific design force: "Multiple vehicle types need different spot sizes, so I'll use Strategy for assignment."
4. Writing too much code
You have 15-20 minutes for code in a 45-minute interview. That's roughly 60-100 lines, not 300. Write the core interfaces, one concrete implementation, and the service that orchestrates them. Declare everything else as stubs or describe them verbally.
5. Forgetting to trace a scenario
Your design exists in your head. The interviewer needs to see it work. Walk through one complete scenario: "A truck arrives, the service calls assignSpot(), the strategy returns the first large spot on floor 2, a ticket is issued, the spot is marked occupied." This is your proof that the design actually hangs together.
6. Ignoring extensibility
The interviewer will almost certainly ask: "What if we need to add electric vehicle spots?" or "What if the pricing changes?" If your design requires modifying five classes to add one feature, that's a red flag. Design for the Open-Closed Principle from the start: new behavior through new classes, not edits to existing ones.
How this shows up in interviews
Typical prompts:
- "Design a parking lot system"
- "Design an elevator system"
- "Design a library management system"
- "Design a vending machine"
What interviewers probe for:
| Interviewer question | What they're really asking | Strong response |
|---|---|---|
| "Walk me through your approach" | Do you have a process? | "I'll start by clarifying requirements, then model entities, define relationships, pick patterns, and implement core classes." |
| "Why did you use inheritance here?" | Can you justify structural decisions? | "Vehicles share a common interface but have type-specific behavior. I used an interface, not abstract class, because there's no shared state." |
| "What if we add a new vehicle type?" | Is the design extensible? | "I'd add a new VehicleType enum value and a new SpotAssignmentStrategy. No existing classes change." |
| "How would you test this?" | Do you think about testability? | "The Strategy interface makes unit testing easy. I can inject a mock strategy into ParkingLotService and verify behavior without real spots." |
| "What patterns did you use?" | Do you recognize and name patterns? | "Strategy for assignment, Observer for occupancy tracking. I considered State for spot lifecycle but it's overkill for two states (occupied/available)." |
The rejection pattern interview cheat sheet
When the interviewer asks "What patterns did you consider but rejected?", have one ready. "I considered the State pattern for parking spot lifecycle, but a spot only has two states (available/occupied), so a boolean is simpler. If spots had maintenance, reserved, and handicapped states, I'd introduce State." This shows depth without over-engineering.
Test Your Understanding
Quick recap
- OOD interviews evaluate five dimensions: requirements gathering, entity modeling, pattern selection, code quality, and trade-off discussions. Code is only 40% of the signal.
- Follow the 5-step framework: Clarify, Identify entities, Define relationships, Choose patterns, Implement and trace.
- Spend roughly 5/10/10/15/5 minutes across the five steps. Set verbal checkpoints at 15 and 30 minutes.
- Name patterns only when you can state the specific force they address. "I'll use Strategy because..." beats "I'll use Strategy" with no context.
- Prefer composition over inheritance. One interface hierarchy and lots of HAS-A relationships handles most problems.
- Write 3-5 core classes, skip boilerplate, and trace one scenario end-to-end as proof that the design works.
- Proactive trade-off discussion is the single biggest separator between mid and senior candidates.
- Over-modeling, pattern name-dropping, and ignoring extensibility are the three fastest ways to a weak-hire signal.