Skip to main content
Scenario Article

LLD for Parking Lot System: Designing a Smart Garage

The Mall Garage Problem

Abstract Algorithmsβ€’Mar 9, 2026
XLinkedInReddit
πŸ’‘ Executive Summary

Entry gate: You press a button β†’ get a ticket β†’ gate opens.

🎯 System Scenario & Requirements

System Goal

Entry gate: You press a button β†’ get a ticket β†’ gate opens.

Actors & Components

  • Application or API tier
  • Core service under design
  • Operator or SRE observer

Functional Requirements

  • Entry gate: You press a button β†’ get a ticket β†’ gate opens.
  • Parking: Find a spot (the system might display "Floor 2, Spot 14").
  • Exit: Scan your ticket β†’ system calculates fee based on time parked β†’ gate opens.

Constraints & Assumptions

⚑ Execution Stages & Decision Trace

1

Stage 1 β€” Parking Lot Design Basics

Action / Decision:

Before writing any code, it helps to map out the real-world entities the system must represent.

Component Behavior:

Spot Types β€” Not every bay fits every vehicle.

Observable Output: A typical garage divides its spaces into three tiers: Vehicle Types β€” Each vehicle carries a licensePlate and a VehicleType enum ( BIKE , CAR , TRUCK ).
Read Full Stage in Deep Dive ↓
πŸ“–

Deep Dive

Detailed Architectural Analysis

Scenario context

You pull up to a mall garage. Three things happen:

  1. Entry gate: You press a button β†’ get a ticket β†’ gate opens.
  2. Parking: Find a spot (the system might display "Floor 2, Spot 14").
  3. Exit: Scan your ticket β†’ system calculates fee based on time parked β†’ gate opens.

The software behind this manages hundreds of concurrent vehicles across multiple floors, spot types, and pricing tiers.


This walkthrough focuses on The Mall Garage Problem.

Before making a design choice, clarify:

  • Entry gate: You press a button β†’ get a ticket β†’ gate opens.
  • Parking: Find a spot (the system might display "Floor 2, Spot 14").
  • Exit: Scan your ticket β†’ system calculates fee based on time parked β†’ gate opens.

Concepts in play: tree-data-structures, low-level-design-systems, vector-databases-rag, design-patterns-gof

Stage 1 β€” Parking Lot Design Basics

  • Before writing any code, it helps to map out the real-world entities the system must represent.
  • Spot Types β€” Not every bay fits every vehicle.
  • A typical garage divides its spaces into three tiers: Vehicle Types β€” Each vehicle carries a licensePlate and a VehicleType enum ( BIKE , CAR , TRUCK ).
  • The type determines which spot tier it can occupy β€” a TRUCK cannot squeeze into a CompactSpot .

Observable outcome: The type determines which spot tier it can occupy β€” a TRUCK cannot squeeze into a CompactSpot .

Stage 2 β€” The Domain Model

  • Hierarchy: - ParkingSpot β†’ subclasses: BikeSpot , CompactSpot , LargeSpot - Vehicle β†’ subclasses: Bike , Car , Truck - ParkingLot β†’ Singleton (one physical lot, one controller)
classDiagram
    class ParkingLot {
        -static ParkingLot instance
        +List~ParkingFloor~ floors
        -PricingStrategy pricingStrategy
        +Ticket park(Vehicle v)
        +double exit(Ticket t)
    }
    class ParkingFloor {
        +int floorNumber
        -Map~VehicleType,PriorityQueue~ heaps
        +ParkingSpot findNearest(VehicleType t)
        +void releaseSpot(ParkingSpot s)
    }
    class ParkingSpot {
        <>
        +int id
        +boolean isFree
        +VehicleType type
        +void assign(Vehicle v)
        +void free()
    }
    class BikeSpot {
        +VehicleType type = BIKE
    }
    class CompactSpot {
        +VehicleType type = CAR
    }
    class LargeSpot {
        +VehicleType type = TRUCK
    }
    class Vehicle {
        <>
        +String licensePlate
        +VehicleType type
    }
    class Bike
    class Car
    class Truck
    class Ticket {
        +Vehicle vehicle
        +ParkingSpot spot
        +Instant entryTime
    }
    class PricingStrategy {
        <>
        +calculateFee(VehicleType type, long minutes) double
    }
    class HourlyPricing {
        +calculateFee(VehicleType type, long minutes) double
    }

    ParkingLot "1" *-- "many" ParkingFloor : owns
    ParkingFloor "1" *-- "many" ParkingSpot : contains
    BikeSpot --|> ParkingSpot : extends
    CompactSpot --|> ParkingSpot : extends
    LargeSpot --|> ParkingSpot : extends
    Bike --|> Vehicle : extends
    Car --|> Vehicle : extends
    Truck --|> Vehicle : extends
    Ticket --> Vehicle : records
    Ticket --> ParkingSpot : records
    ParkingLot o-- PricingStrategy : uses
    HourlyPricing ..|> PricingStrategy : implements

Observable outcome: Hierarchy: - ParkingSpot β†’ subclasses: BikeSpot , CompactSpot , LargeSpot - Vehicle β†’ subclasses: Bike , Car , Truck - ParkingLot β†’ Singleton (one physical lot, one controller)

Stage 3 β€” OOP Pillars in the Parking Lot Domain

  • The four OOP pillars are not abstract ideals here β€” each one maps to a concrete class or interface in this design.
  • Encapsulation β€” ParkingFloor hides its Min-Heap ParkingFloor owns a Map<VehicleType, PriorityQueue<ParkingSpot internally.
  • No external class ever touches that map directly.
  • The public surface is exactly two methods: findNearest(VehicleType) (wraps poll() ) and releaseSpot(ParkingSpot) (wraps offer() ).
stateDiagram-v2
    [*] --> AVAILABLE : spot added to Min-Heap
    AVAILABLE --> OCCUPIED : findNearest()  assign(vehicle)
    OCCUPIED --> AVAILABLE : releaseSpot()  re-insert into heap
    AVAILABLE --> [*] : floor decommissioned

Observable outcome: The public surface is exactly two methods: findNearest(VehicleType) (wraps poll() ) and releaseSpot(ParkingSpot) (wraps offer() ).

Stage 4 β€” Finding the Nearest Spot: Min-Heap

  • A naive O(N) linear scan through all spots is too slow for a large garage.
  • Optimized: Use a Min-Heap (priority queue ordered by spot ID, lowest = nearest entrance) per vehicle type per floor.
  • Operations: - findNearest(CAR) β†’ heaps.get(CAR).poll() β†’ O(log N) - releaseSpot(spot) β†’ heaps.get(spot.type).offer(spot) β†’ O(log N) For N = 1000 spots per floor: logβ‚‚(1000) β‰ˆ 10 operations vs.
Floor 1 Compact Heap: [101, 103, 107, ...]   ← pop 101 in O(log N)
Floor 1 Large Heap:   [150, 155, ...]

Observable outcome: Operations: - findNearest(CAR) β†’ heaps.get(CAR).poll() β†’ O(log N) - releaseSpot(spot) β†’ heaps.get(spot.type).offer(spot) β†’ O(log N) For N = 1000 spots per floor: logβ‚‚(1000) β‰ˆ 10 operations vs.

Stage 5 β€” Deep Dive: Factory and Strategy Patterns

  • Callers use VehicleFactory.create(VehicleType.CAR, "ABC-123") β€” never new Car(...) directly.
  • This decouples object creation from business logic and makes it easy to add ElectricVehicle later.
public class VehicleFactory {
    public static Vehicle create(VehicleType type, String plate) {
        return switch (type) {
            case BIKE   -> new Bike(plate);
            case CAR    -> new Car(plate);
            case TRUCK  -> new Truck(plate);
        };
    }
}

Observable outcome: This decouples object creation from business logic and makes it easy to add ElectricVehicle later.

Stage 6 β€” Strategy Pattern for Pricing

  • Pricing rules vary (hourly, daily, weekend, EV charging surcharge): The ParkingLot holds a reference to any PricingStrategy .
  • Swapping from HourlyPricing to DynamicPricing requires zero changes to the rest of the code.
  • πŸ“Š Factory and Strategy: Class Diagram This class diagram extends the core domain model to show the full Factory and Strategy pattern integration, including the VehicleFactory creation point, the pluggable PricingStrate…
  • The key relationship is that ParkingLot depends on interfaces ( PricingStrategy , SpotAllocator ) rather than concrete classes, which is what allows EVSpot and ChargingPricing to be added without modifying any existing…
public interface PricingStrategy {
    double calculateFee(VehicleType type, long parkingMinutes);
}

public class HourlyPricing implements PricingStrategy {
    public double calculateFee(VehicleType type, long minutes) {
        double ratePerHour = type == VehicleType.TRUCK ? 3.50 :
                             type == VehicleType.CAR   ? 2.00 : 1.00;
        return ratePerHour * Math.ceil(minutes / 60.0);
    }
}
classDiagram
    class VehicleFactory {
        +create(VehicleType, String) Vehicle
    }
    class PricingStrategy {
        <>
        +calculateFee(VehicleType, long) double
    }
    class HourlyPricing {
        +calculateFee(VehicleType, long) double
    }
    class ChargingPricing {
        +calculateFee(VehicleType, long) double
    }
    class SpotAllocator {
        <>
        +findNearest(VehicleType, List~ParkingFloor~) Optional~ParkingSpot~
        +release(ParkingSpot, List~ParkingFloor~) void
    }
    class NearestFirstAllocator {
        +findNearest(VehicleType, List~ParkingFloor~) Optional~ParkingSpot~
        +release(ParkingSpot, List~ParkingFloor~) void
    }
    class EVSpot {
        +chargerType String
        +canFit(VehicleType) boolean
    }
    class ParkingLot {
        -PricingStrategy pricingStrategy
        -SpotAllocator allocator
        +park(Vehicle) Ticket
        +exit(Ticket) double
    }
    HourlyPricing ..|> PricingStrategy : implements
    ChargingPricing ..|> PricingStrategy : implements
    NearestFirstAllocator ..|> SpotAllocator : implements
    ParkingLot o-- PricingStrategy : uses (injected)
    ParkingLot o-- SpotAllocator : uses (injected)
    VehicleFactory --> Vehicle : creates
    EVSpot --|> ParkingSpot : extends

Observable outcome: The key relationship is that ParkingLot depends on interfaces ( PricingStrategy , SpotAllocator ) rather than concrete classes, which is what allows EVSpot and ChargingPricing to be added without modifying any existing…

End-to-end outcome

Entry gate: You press a button β†’ get a ticket β†’ gate opens.

Alternatives considered

Decision Guide: When to Apply These Parking Lot Patterns

Start simple: a flat HashMap<SpotId, Spot works for a garage under 50 spots.

Failure and degraded modes

Trade-offs & Failure Modes in Parking Lot Design

  • Detection: Trade-offs & Failure Modes in Parking Lot Design
  • User or operator impact: Trade-offs & Failure Modes in Parking Lot Design

Share this case study

Discuss architecture trade-offs and lessons with your team.

Share:XLinkedInReddit