Course Content
Object-Oriented Design Interview
14 sections · 29 lessons
Shipping Locker: recognising the shape, requirements and objects
This problem is in the course to test a skill rather than teach a new structure: noticing that a new prompt is an old one wearing different nouns. This lesson covers the prompt, the recognition and where it stops holding, the requirements, and the objects — most of which you have already built once.
Why this is the self-test problem
Look at the shape of what you drew. A location contains banks, banks contain lockers, lockers come in sizes, a parcel needs the smallest locker it fits in, a locker can hold zero or one parcel at a time, and two couriers must not be assigned the same locker.
That is the parking lot from Section 4 with different nouns.
| Parking lot | Locker network |
|---|---|
ParkingLot | LockerLocation |
Floor | LockerBank |
ParkingSpot (small/medium/large) | Locker (small/medium/large) |
Vehicle needs a fitting spot | Parcel needs a fitting locker |
Ticket — issued on entry, closed on exit | Reservation — created on drop-off, closed on pickup |
| Allocation strategy (smallest fitting) | Allocation strategy (smallest fitting) |
| Two cars, one last spot | Two couriers, one last locker |
This is the actual skill this course builds. Not memorising eleven designs, but recognising that a new prompt is an old one wearing different nouns. In an interview you will be given a problem this course does not contain — a library, a hotel, a bike-share, a car-rental desk — and the winning move is to notice within two minutes which shape it is.
So a useful exercise now: compare your attempt against your parking lot attempt. If you rediscovered the same structure from scratch, that is fine and normal. If you recognised it and reused the shape, you are doing the thing this course is for.
Where the analogy breaks
Puncture it, because a transferred pattern applied blindly is its own failure.
Three differences make this problem genuinely its own:
- Time is a first-class concern. A car leaves when it leaves. A parcel has a deadline — it must be collected within, say, three days, and then it is reclaimed. Expiry is a requirement, not an extension.
- Access is authenticated. Anyone can drive out of a car park with their own car. Opening a locker needs a single-use code, and code generation, delivery, expiry, and validation are all design surface.
- There are two different users. A courier drops off and a recipient collects, and they have different permissions and different flows. The parking lot has one actor.
Those three are where your design should differ from the parking lot's, and they are what the interviewer will spend their time on.
The four questions that change the model
1. "How are lockers sized, and what if the right size is unavailable?" Same question as the parking lot, same answer shape: a parcel may use its own size or larger, never smaller. Ask what happens when nothing fits — refuse the drop-off, or route to another location?
2. "How long may a parcel sit before it is reclaimed?" Assume three days, configurable. This creates the expiry state.
3. "How is pickup authenticated — a code, an app, a barcode?" Assume a numeric code sent by message, single-use. Ask whether the recipient can be someone else — parcel handover is a real requirement in some networks.
4. "What happens to an expired parcel?" It is returned to the courier or the sender. Someone must physically remove it, which means a courier-facing reclaim flow, not an automatic state change.
Requirements
Functional requirements
1. Courier drop-off: find a free locker that fits the parcel, open it, record the parcel2. Notify the recipient with a single-use access code and a deadline3. Recipient pickup: validate the code, open the correct locker, mark it free4. Reclaim: after the deadline, mark the parcel expired and make it collectable by a courier5. Query availability at a location, by sizeNon-functional requirements
N1. A locker must never be double-assigned. Two couriers at the same bank, and the same concurrency case as the parking lot extensions — with one difference that makes it worse: a courier who opens a locker that already holds someone else's parcel has caused a privacy incident, not an inconvenience.
N2. Access codes must be single-use and expire. A code that works twice means a parcel can be collected by whoever collected the previous one from that locker.
N3. Availability lookup must not scan every locker at a location. Same as the parking lot.
N4. Allocation policy must be replaceable. Smallest-fitting today; a network may later want "lowest locker for accessibility" or "spread the wear across banks".
What is cut
CUT (named, not forgotten)- Physical lock hardware and its protocol (an interface)- Courier routing, vehicles, and delivery scheduling- Payment for the service- Parcel tracking upstream of the locker (that is a different system)- The recipient's app or websiteThe requirement that surprises people
Write this one down explicitly, because it is the difference between a design that works and one that works on Wednesday:
A locker holds one parcel at a time, but a locker is reused several times a day.
That single sentence has two consequences. Locker cannot hold parcel history — it holds the current parcel and nothing else. And the historical record ("who collected what, when") lives on Reservation, which is created per drop-off and never reused.
That is the same insight as Seat versus ShowSeat in Section 5 and Product versus InventoryItem in Section 9: the permanent physical thing and the per-use record are two classes. Third appearance in this course, which is why it is worth naming as a pattern rather than as a fact about lockers.
Finding the objects
The candidate nouns
Location, bank, locker, size, parcel, courier, recipient, code, reservation, notification, deadline, pickup, drop-off.
One sentence per class
LockerLocation — a physical site holding one or more banks of lockers.LockerBank — one cabinet of lockers with its own controller and screen.Locker — one compartment: its size, its state, and the parcel currently inside.Parcel — one item to be delivered: its size, its recipient, and its tracking id.Reservation — the record of one parcel's stay: which locker, from when, until when.AccessCode — a single-use credential tied to one reservation, with an expiry.Courier — who drops off and who reclaims.Recipient — who collects.Every one passes. Two are worth defending.
Reservation rather than putting dates on Locker. A locker is reused several times a day (the requirement that surprises people, above), so drop-off time, deadline, and collection time cannot live on it. Reservation is created per drop-off, holds the timeline, and outlives the locker's use of it — which is what makes "how many parcels expired at this location last month?" answerable.
AccessCode as a class rather than a String on Reservation. This is the borderline one, and the reasoning is worth saying out loud: a code has a value, an expiry, a used-flag, and a validation rule. That is state plus behaviour, which passes the filters from Phase 3: finding classes. A bare string forces the validation logic somewhere else, and "somewhere else" ends up being the same class that opens lockers.
1public class AccessCode {2 private final String value; // hashed in storage, see the access code lesson3 private final Instant expiresAt;4 private boolean used;56 public boolean validate(String attempt, Instant now) {7 return !used && now.isBefore(expiresAt) && constantTimeEquals(value, attempt);8 }9 public void markUsed() { this.used = true; }10}LockerSize: an enum with ordering
Identical in shape to SpotSize in Spot assignment, in code:
1public enum LockerSize {2 SMALL(1), MEDIUM(2), LARGE(3), OVERSIZED(4);3 private final int rank;4 public boolean fits(ParcelSize p) { return this.rank >= p.rank(); }5}Say the reuse out loud: "This is the same fitting rule as spot sizes in a parking lot — a parcel takes its own size or larger, never smaller, and I'll encode the ordering in the enum rather than in branches." Naming the transfer is not a shortcut; it is the demonstration.