OO Design Problems
Step 8 in the OO & Low-Level Design path · 16 concepts · 0 problems
📘 Learn OO Design Problems from zero
Low-level design rewards a calm, repeatable process far more than memorizing patterns. Here is the expert loop:
- Read & restate. Say back what the system does in one sentence and confirm scope with the interviewer. "Design a parking lot" could mean a single garage or a multi-city network — pin it down before drawing anything.
- Clarify constraints & requirements. Enumerate the core functional use cases (book a ticket, park a car, post an answer) and explicitly mark non-goals. List the actors and the 3-5 must-have flows. This becomes your checklist and bounds the problem.
- Brute-force the model first. Extract nouns as candidate classes and verbs as candidate methods. Write the obvious objects with plain fields and the relationships between them, even if naive. A working object model beats a clever empty one.
- Spot the pattern. Re-read your model for the signals above: states & transitions, reactions to events, interchangeable behaviors, varied construction, undoable requests. Apply a pattern only where it removes real
if/elsesprawl or absorbs anticipated change — patterns are a response to variation, not decoration. - Apply the SOLID principles. Push for single responsibility, composition over inheritance, and programming to interfaces (dependency inversion). Draw the class diagram with explicit relationships — association, aggregation, composition — and the cardinalities.
- Edge cases & concurrency. Double-booking, payment failure, capacity overflow, invalid state transitions, and thread-safety on shared managers. Name the concrete mechanism (lock, atomic counter, version check), not just "handle concurrency."
- Test by walking a use case. Trace one end-to-end flow through your classes aloud to prove the API hangs together and the methods compose.
Stay narrative — think out loud so the interviewer follows your reasoning. They are scoring your judgment and how you decompose responsibility, not a pixel-perfect UML.
✨ Added by the guide to build intuition — not from the source course.
🎯 Guided practice
Worked example: Design a Movie Ticket Booking System.
- Restate & scope. "Users browse movies and showtimes across cinemas, select seats, and pay to book a ticket." Confirm: single city vs. chain, assigned seats vs. general admission, refunds in scope. Assume a chain with assigned seats.
- Nouns → classes.
Movie,Cinema,CinemaHall(screen),Show,Seat(physical),ShowSeat(a seat bound to one specific show — this is where availability and price live),Booking,Payment,User. Verbs → methods:searchMovies(),getAvailableSeats(),book(),pay(),cancel(). - Signal: the booking has states and transitions — Requested → Pending (seats held) → Confirmed → Canceled/Expired. That signal points to a State pattern (or an explicit state machine on
Booking) so each transition is validated in one place, not scattered across booleans. - Signal: payment is one of several interchangeable behaviors (credit card, wallet, UPI). That points to a Strategy pattern: a
PaymentStrategyinterface with concrete implementations chosen at runtime. - The hard signal — concurrency. Two users grabbing the same seat is the crux of this problem. The standard technique is a short-lived seat hold on each
ShowSeatwith a timeout — e.g., aSeatLockProviderthat places a pessimistic lock (or writes a hold row with a 5-minute TTL) before payment, so a second buyer sees the seat as unavailable. Then enforce the commit with a single atomic conditional update on theShowSeatrow (the optimistic-locking version check) so exactly oneBookingcan flip it to Booked even if two reach the database. Make the payment step idempotent (idempotency key) so a retry never double-charges, and release the hold on timeout. - Signal: notify on events (booking confirmed → email/SMS) → Observer pattern: subscribers register on the booking lifecycle.
- Construction & wiring: a
BookingServiceorchestrates the flow; use a Factory forPayment/PaymentStrategycreation, and keep collaborators injected (avoid a hard Singleton) for testability.
Optimal shape: a BookingService that (1) holds the chosen ShowSeats via the lock provider, (2) drives Booking through its state machine, (3) delegates charging to a PaymentStrategy idempotently, (4) on success commits the seats with the atomic version check and notifies observers, and on timeout or failure releases the holds. The teachable insight: the seat-contention signal — not the class list — is what drives the whole design.
✨ Added by the guide — work these before the full problem set.
Lessons in this topic
- ○Design a Library Management System
- ○Design a Parking Lot
- ○Design Amazon Online Shopping System
- ○Design Stack Overflow
- ○Design a Movie Ticket Booking System
- ○Design an ATM
- ○Design an Airline Management System
- ○Design Blackjack and a Deck of Cards
- ○Design a Hotel Management System
- ○Design a Restaurant Management system
- ○Design Chess
- ○Design an Online Stock Brokerage System
- ○Design a Car Rental System
- ○Design LinkedIn
- ○Design Cricinfo
- ○Design Facebook a social network