How would you extend the parking lot design for multiple locations?
Fast recall
Quick revision
Core answer
Extensibility thinking—can the candidate evolve a design to handle new requirements without breaking existing abstractions or creating tight coupling.
Trying to retrofit ParkingLot as a multi-location entity, violating Single Responsibility Principle and creating a tangled design.
Discuss how the network layer could use the Composite pattern to treat single lots and lot collections uniformly, enabling recursive aggregation.
Interview-ready guide
Interview answer
The clean way to support multiple locations is to add a new layer above the existing design rather than changing the lot itself. I'd create a ParkingLotNetwork class that holds a collection of ParkingLot instances — usually a map keyed by lot id. Each individual lot stays exactly as it was, with its own floors and spots. That's the Open/Closed Principle: I'm extending the system by adding a class, not modifying working code.
The network is where cross-location features live. For finding the nearest lot with a free spot, the network takes the user's location, filters to lots that have availability, and picks the one with the smallest distance. For total occupancy, it just streams over all lots and sums their counts. The key idea is that the network coordinates and aggregates, but the actual parking logic stays inside ParkingLot where it belongs.
To make it really clean, I'd extract an IParkingLot interface with the common operations, and have both ParkingLot and ParkingLotNetwork implement it. Now calling code can talk to either one without knowing whether it's a single lot or a whole network — that's the Composite pattern.
Adding a neighbours list directly to ParkingLot creates the wrong dependency. That makes every lot aware of the others, creates circular dependencies, and violates single responsibility. Each lot should only know about its own floors and spots; the network handles everything that spans locations. In a real system, each lot could even be its own microservice with the network acting as an API gateway routing by geography.
For example, findNearestAvailable(userLocation, CAR) can filter lots without a compatible spot and rank the rest by distance. It returns a candidate lot, but that lot still performs the final atomic reservation because the network's availability view may already be stale.
How would you extend the parking lot design for multiple locations
Direct Answer
Introduce a ParkingLotNetwork or ParkingManagementSystem class that aggregates multiple ParkingLot instances. Each ParkingLot remains an independent unit with its own floors and spots. The network layer provides cross-location operations like findNearestAvailableSpot(Location userLocation) or getTotalOccupancyAcrossAllLots().
Deep Dive & Architecture
Each location remains its own aggregate
A ParkingLot continues to own its floors, spots, tickets, and local allocation rules. A ParkingNetwork keeps a map of lot ids to lots and handles operations that cross location boundaries. This avoids coupling every lot to every other lot.
The network coordinates a concrete lookup
For example, if lots A, B, and C report availability, findNearestAvailable(userLocation, CAR) filters out lots without a car spot, calculates distance for the remaining lots, and returns the closest candidate. The chosen lot must still reserve the spot; a network-level availability count is only a snapshot and cannot guarantee the spot remains free.
Distribution changes the freshness boundary
In one process, the network may call lot objects directly. With remote locations, each lot can publish occupancy updates and expose a reservation API. The network may serve slightly stale search results, but the location is the final authority for a claim. That separation lets search scale independently without weakening the no-double-booking rule inside each lot.
Code Example
record GeoLocation(double lat, double lng) {}
interface IParkingLot { // shared contract (Composite)
Optional<ParkingTicket> park(Vehicle v);
int availableCount();
}
class ParkingLot implements IParkingLot { /* unchanged single-lot logic */ }
class ParkingLotNetwork implements IParkingLot {
private final Map<String, ParkingLot> lots = new HashMap<>();
// Cross-location operation the single lot never needed
Optional<ParkingLot> nearestWithSpace(GeoLocation user, SpotSize size) {
return lots.values().stream()
.filter(l -> l.availableCount() > 0)
.min(Comparator.comparingDouble(l -> distance(user, l.location())));
}
public Optional<ParkingTicket> park(Vehicle v) { // delegate to a lot
return lots.values().stream().map(l -> l.park(v))
.filter(Optional::isPresent).map(Optional::get).findFirst();
}
public int availableCount() {
return lots.values().stream().mapToInt(ParkingLot::availableCount).sum();
}
}
ParkingLot is untouched — the network only aggregates and delegates.
Common Mistakes & Pitfalls
- Adding a
neighborslist toParkingLot— creates circular references and makes each lot know about others. Coordination belongs in the network layer. - Duplicating spot-search logic in the network — it should delegate to each lot, not re-implement parking (DRY).
- No lot identity — each lot needs an id and
GeoLocation, or you can't route or report per-lot. - Modifying
ParkingLotat all — if you're editing it, you've missed the Open/Closed point.
Check your understanding
Answer these without looking back at the article.
- Design a parking lot system. Walk me through your approach.
- How does the fee calculation work in your parking lot design?
- What design patterns did you apply in the parking lot design and why?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.