Designing a Parking Lot System
Designing a parking lot system is a classic low-level system design question that tests your ability to model real-world entities using object-oriented principles, apply design patterns, and build scalable, extensible software.
Requirements
The system should satisfy the following:
- The parking lot should have multiple levels, each with a number of parking spots.
- It should support different types of vehicles such as cars, motorcycles, and trucks.
- Each parking spot must be suitable for a specific type of vehicle.
- On vehicle entry, assign an appropriate parking spot; on exit, release it.
- Track the availability of spots in real-time.
- Handle multiple entry/exit points and support concurrent access.
Problem Analysis
Before jumping into code or class diagrams, a thorough problem analysis helps in:
- Identifying key entities (Vehicle, ParkingSpot, Level, etc.)
- Defining relationships (A Level has many ParkingSpots)
- Recognizing constraints (e.g., spot types must match vehicle types)
- Understanding concurrency needs (multiple entries/exits)
Clarifying Ambiguities:
- What if all spots are full?
- Can trucks park across multiple spots?
- Should we track time parked or fees?
Use clarifying questions in interviews to refine requirements. Create assumptions when needed, but always state them clearly.
Class and Interface Design
Break down responsibilities into clear, cohesive components using SOLID principles:
- Vehicle – base class with
Car
,Motorcycle
,Truck
as subclasses - ParkingSpot – abstract class with types:
CompactSpot
,LargeSpot
, etc. - Level – contains multiple
ParkingSpots
- ParkingLot – manages levels and availability
- Ticket – issued on entry, used on exit
- EntryGate / ExitGate – interfaces for managing entry/exit flow
Key Design Ideas:
- Use composition for Level → ParkingSpots
- Use inheritance for Vehicle and Spot hierarchies
- Use interfaces for entry/exit logic
Implementation Strategies
- Use a
Map<VehicleType, List<ParkingSpot>>
for fast spot lookups - Store a global
Set<Ticket>
for current parkings - Use
ReentrantLock
orsynchronized
blocks to handle concurrent access - Use enums for
VehicleType
andSpotType
Design Patterns Applied
- Singleton – Ensure only one instance of
ParkingLot
exists - Factory – Create
Vehicle
orParkingSpot
based on type - Strategy – Implement spot allocation strategies
- Observer – Notify availability boards when a spot is filled or released
Example Java Classes
public class ParkingLot {
private static final ParkingLot INSTANCE = new ParkingLot();
private List<Level> levels;
private ParkingLot() {
this.levels = new ArrayList<>();
}
public static ParkingLot getInstance() {
return INSTANCE;
}
public Ticket parkVehicle(Vehicle vehicle) {
for (Level level : levels) {
Ticket ticket = level.park(vehicle);
if (ticket != null) return ticket;
}
return null; // No spot found
}
public void unparkVehicle(Ticket ticket) {
ticket.getSpot().free();
}
}