LLDLLD Case StudiesDesign a Parking Lot

Design a Parking Lot

LLD Case Studies

This is another very common LLD interview question. The goal is to design a system that can manage the parking of vehicles in a multi-level parking lot. The interviewer is looking for your ability to handle complexity, identify entities, and design a flexible system.

1. Clarify Requirements

  • What types of vehicles can be parked? Cars, Motorcycles, Buses.
  • How many parking spots are there? The system should be configurable for different numbers of floors and spots per floor.
  • What are the different spot sizes? Small (for motorcycles), Medium (for cars), Large (for buses).
  • How is parking allocated? The system should find the nearest available spot of the correct size.
  • How is pricing calculated? Pricing is based on the duration of the stay. Let's assume a simple hourly rate.
  • How does a user enter and exit? A user takes a Ticket upon entry and pays at an exit terminal before leaving.
  • What information is on the ticket? Spot number, vehicle type, and entry time.

2. Identify the Core Classes and Objects

  • ParkingLot: The main entry point of the system.
  • Floor: Represents a single floor in the parking lot.
  • ParkingSpot: Represents a single spot. It will be an abstract class with subclasses like MotorcycleSpot, CarSpot, LargeSpot.
  • Vehicle: An abstract class representing a vehicle, with subclasses for Motorcycle, Car, Bus.
  • Ticket: An object that stores information about a parked vehicle.
  • PaymentStrategy: An interface to handle different payment methods (e.g., hourly, daily).

3. Design the System - Class Diagram

ParkingLotFloorTicket<<abstract>>ParkingSpotMotorcycleSpotCarSpotLargeSpot<<abstract>>VehicleMotorcycleCarBus11..*11..*10..10..110..11

4. Key Design Decisions & Implementation Details

Handling Vehicle Sizes:

A key challenge is fitting vehicles into spots. A car shouldn't park in a motorcycle spot, but a motorcycle can park in a car spot. We can handle this with an enum for sizes and a check in our allocation logic.

public abstract class ParkingSpot {
    private String spotId;
    private boolean isOccupied;
    private Vehicle vehicle;
    private final SpotSize size;

    public ParkingSpot(String id, SpotSize size) {
        this.spotId = id;
        this.size = size;
        this.isOccupied = false;
    }

    public boolean canFitVehicle(Vehicle v) {
        return this.size.canAccommodate(v.getSize());
    }
    // ... getters and setters
}

public enum SpotSize {
    SMALL, MEDIUM, LARGE;

    public boolean canAccommodate(VehicleSize vSize) {
        return this.ordinal() >= vSize.ordinal();
    }
}

Finding an Available Spot:

The ParkingLot class will delegate the task of finding a spot to its Floor objects.

public class ParkingLot {
    private List<Floor> floors;

    public Ticket parkVehicle(Vehicle vehicle) {
        for (Floor floor : floors) {
            Optional<ParkingSpot> spot = floor.findAvailableSpot(vehicle);
            if (spot.isPresent()) {
                // 1. Assign vehicle to spot
                // 2. Generate a ticket
                // 3. Return the ticket
                return generateTicket(vehicle, spot.get());
            }
        }
        throw new RuntimeException("No available spot found.");
    }
    // ...
}

Key Discussion Points

  • Abstract Classes vs. Interfaces: Be ready to justify your use of abstract classes for Vehicle and ParkingSpot. An abstract class is a good choice here because you want to provide common, shared implementation (like spotId, isOccupied) while forcing subclasses to provide their own specific logic if needed.
  • Scalability: How would you handle a parking lot with thousands of spots? The current linear search (for (Floor floor : floors)) might be slow. You could discuss maintaining a count of available spots of each size for each floor, allowing you to quickly identify if a floor has any potential spots before you start iterating through them.
  • Payment System: The use of a PaymentStrategy interface is a good example of the Strategy Pattern. This decouples the Ticket or exit terminal from the specific pricing logic. You can easily add new pricing models (e.g., FlatRateStrategy, WeekendRateStrategy) without changing the core parking flow.
  • Extensibility: How would you add features like a display board showing available spots? You could use the Observer Pattern. The Floor or ParkingSpot objects would be the "Subjects," and a DisplayBoard object would be an "Observer" that gets notified whenever a spot's isOccupied status changes.