All Posts

LLD for Parking Lot System: Designing a Smart Garage

Designing a parking lot is the 'Hello World' of System Design. We break down the Low-Level Design (LLD) using the Factory and Strategy patterns.

Abstract AlgorithmsAbstract Algorithms
ยทยท4 min read
Share
Share on X / Twitter
Share on LinkedIn
Copy link

TLDR: A Parking Lot system is the "Hello World" of Low-Level Design interviews. The core challenges are allocation (finding the nearest available spot in O(log n)) and pricing (calculating fees based on vehicle type and duration). Factory Pattern for vehicles, Strategy Pattern for pricing.


๐Ÿ“– The Mall Garage Problem

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.


๐Ÿ”ข The Domain Model

classDiagram
    class ParkingLot {
        -static ParkingLot instance
        +List~ParkingFloor~ floors
        +Ticket park(Vehicle v)
        +double exit(Ticket t)
    }
    class ParkingFloor {
        +int floorNumber
        +ParkingSpot findNearest(VehicleType t)
        +void releaseSpot(ParkingSpot s)
    }
    class ParkingSpot {
        <>
        +int id
        +boolean isFree
        +VehicleType type
    }
    class Vehicle {
        <>
        +String licensePlate
        +VehicleType type
    }
    class Ticket {
        +Vehicle vehicle
        +ParkingSpot spot
        +Instant entryTime
    }

    ParkingLot *-- ParkingFloor
    ParkingFloor *-- ParkingSpot
    Ticket --> Vehicle
    Ticket --> ParkingSpot

Hierarchy:

  • ParkingSpot โ†’ subclasses: BikeSpot, CompactSpot, LargeSpot
  • Vehicle โ†’ subclasses: Bike, Car, Truck
  • ParkingLot โ†’ Singleton (one physical lot, one controller)

โš™๏ธ 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.

Floor 1 Compact Heap: [101, 103, 107, ...]   โ† pop 101 in O(log N)
Floor 1 Large Heap:   [150, 155, ...]

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. 1000 for linear scan.


๐Ÿง  Factory Pattern for Vehicle Creation

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);
        };
    }
}

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.


โš™๏ธ Strategy Pattern for Pricing

Pricing rules vary (hourly, daily, weekend, EV charging surcharge):

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);
    }
}

The ParkingLot holds a reference to any PricingStrategy. Swapping from HourlyPricing to DynamicPricing requires zero changes to the rest of the code.


โš–๏ธ Design Patterns Summary

PatternApplied ToBenefit
SingletonParkingLotOne physical lot, one controller; no duplicate state
Factory MethodVehicleFactoryDecouple vehicle creation; easy to add new types
StrategyPricingStrategySwap pricing rules (hourly/daily/EV) without touching lot logic
Min-HeapParkingFloor.availableSpotsO(log n) nearest-spot allocation
Template MethodParkingSpot.assign()/free()Common lifecycle in abstract base class

๐Ÿ“Œ Summary

  • Singleton ParkingLot prevents duplicate instance state.
  • Min-Heap per vehicle type per floor โ†’ O(log N) nearest-spot allocation vs. O(N) naive scan.
  • Factory Pattern decouples vehicle creation from business logic.
  • Strategy Pattern keeps pricing rules pluggable and testable in isolation.
  • See the companion post Implement LLD for Parking Lot for the full thread-safe Java implementation.

๐Ÿ“ Practice Quiz

  1. Why is a Min-Heap better than a List for tracking available spots?

    • A) Min-Heap supports more vehicle types.
    • B) Min-Heap gives O(log N) for nearest-spot pop and spot release vs O(N) linear scan.
    • C) Min-Heap prevents overlapping spots.
      Answer: B
  2. What does the Factory Pattern give you in vehicle creation?

    • A) Thread safety for concurrent gate access.
    • B) A single creation point that decouples new Car() from business logic, making it easy to extend with new types.
    • C) A way to pool and reuse Vehicle objects.
      Answer: B
  3. You want to add "peak-hour surcharge" pricing. With the Strategy Pattern, how many existing classes do you need to change?

    • A) All classes that calculate fees.
    • B) Zero โ€” create a new PeakHourPricing implements PricingStrategy and inject it into ParkingLot.
    • C) ParkingLot, Ticket, and ParkingFloor all need updates.
      Answer: B

Abstract Algorithms

Written by

Abstract Algorithms

@abstractalgorithms