π Designing a Scalable Parking Lot System: Low-Level Design (LLD) Step by Step
Imagine youβve just driven into a smart parking lot β no attendants, no hassle, just technology at work. π’π¦
But how does the system know where to park your car? How does it track which spots are free? How does it handle different types of vehicles?
Today, weβll build a Parking Lot System from scratch, step by step, in object-oriented design (OOD) with clean, extensible, and maintainable code. π οΈ
ποΈ Step 1: Understanding the Problem
Before jumping into code, letβs break down what we need.
π― Functional Requirements
- β Vehicles can enter and exit the parking lot.
- β The system should assign an available parking spot.
- β Different vehicle types (bike, car, truck) need different-sized spots.
- β Keep track of occupied and free spots.
- β Payments should be handled for parking time.
π₯ Non-Functional Requirements
- Scalability: Should handle multiple levels in a large parking structure.
- Extensibility: Adding new vehicle types should be easy.
- Performance: Quick allocation of parking spots.
π οΈ Step 2: Identifying Core Entities
We need Objects & Relationships π
- ParkingLot β The main system controlling everything.
- ParkingFloor β Each floor has multiple spots.
- ParkingSpot β Individual slots for vehicles.
- Vehicle β Represents different vehicle types.
- Ticket β Issued when a vehicle enters, used for payment.
- PaymentProcessor β Handles fees and transactions.
π Letβs convert these into code!
π‘ Step 3: Defining the Core Classes
1οΈβ£ Vehicle Class πποΈπ
Every vehicle has a license plate and a size (small, medium, large).
from enum import Enum
class VehicleType(Enum):
BIKE = 1
CAR = 2
TRUCK = 3class Vehicle:
def __init__(self, license_plate: str, vehicle_type: VehicleType):
self.license_plate = license_plate
self.vehicle_type = vehicle_type def __str__(self):
return f"{self.vehicle_type.name} - {self.license_plate}"
2οΈβ£ Parking Spot Class π ΏοΈ
Each parking spot can be occupied or free and has a size.
class ParkingSpot:
def __init__(self, spot_id: int, size: VehicleType):
self.spot_id = spot_id
self.size = size
self.occupied = False
self.vehicle = None # Stores the parked vehicle
def park_vehicle(self, vehicle: Vehicle):
if self.occupied:
return False
if vehicle.vehicle_type.value > self.size.value: # Vehicle too big for the spot
return False
self.vehicle = vehicle
self.occupied = True
return True def remove_vehicle(self):
self.vehicle = None
self.occupied = False def __str__(self):
return f"Spot {self.spot_id} [{self.size.name}] - {'Occupied' if self.occupied else 'Free'}"
3οΈβ£ Parking Floor Class π’
Each floor has multiple parking spots.
class ParkingFloor:
def __init__(self, floor_number: int, spots: list):
self.floor_number = floor_number
self.spots = spots # List of ParkingSpot objects
def find_available_spot(self, vehicle: Vehicle):
for spot in self.spots:
if not spot.occupied and vehicle.vehicle_type.value <= spot.size.value:
return spot
return None # No available spot def __str__(self):
return f"Floor {self.floor_number}: " + ", ".join(str(spot) for spot in self.spots)
4οΈβ£ Parking Lot Class ποΈ
The brain of the system. It manages floors and assigns spots.
class ParkingLot:
def __init__(self, floors: list):
self.floors = floors # List of ParkingFloor objects
self.active_tickets = {} # {ticket_id: (vehicle, parking_spot)}
def park_vehicle(self, vehicle: Vehicle):
for floor in self.floors:
spot = floor.find_available_spot(vehicle)
if spot:
spot.park_vehicle(vehicle)
ticket_id = f"T-{vehicle.license_plate}"
self.active_tickets[ticket_id] = (vehicle, spot)
print(f"β Vehicle {vehicle} parked at {spot} on Floor {floor.floor_number}. Ticket: {ticket_id}")
return ticket_id
print("β No available spots!")
return None def remove_vehicle(self, ticket_id: str):
if ticket_id not in self.active_tickets:
print("β Invalid ticket!")
return False
vehicle, spot = self.active_tickets.pop(ticket_id)
spot.remove_vehicle()
print(f"π Vehicle {vehicle} removed from {spot}.")
return True
5οΈβ£ Payment Processor π°
import time
class PaymentProcessor:
def __init__(self, rate_per_hour=10):
self.rate_per_hour = rate_per_hour def calculate_fee(self, parked_time_seconds):
hours = max(1, parked_time_seconds // 3600) # Charge at least 1 hour
return hours * self.rate_per_hour def process_payment(self, ticket_id, entry_time):
parked_time = time.time() - entry_time
fee = self.calculate_fee(parked_time)
print(f"π³ Payment of ${fee} processed for Ticket {ticket_id}.")
return fee
π Step 4: Simulating the Parking Lot
# Create parking spots
spots1 = [ParkingSpot(i, VehicleType.CAR) for i in range(1, 6)]
spots2 = [ParkingSpot(i, VehicleType.BIKE) for i in range(6, 11)]
floor1 = ParkingFloor(1, spots1 + spots2)
# Create Parking Lot
parking_lot = ParkingLot([floor1])# Simulate Parking
vehicle1 = Vehicle("ABC123", VehicleType.CAR)
ticket1 = parking_lot.park_vehicle(vehicle1)# Simulate Exit
import time
entry_time = time.time()
time.sleep(2) # Simulate parking durationpayment_processor = PaymentProcessor()
payment_processor.process_payment(ticket1, entry_time)
parking_lot.remove_vehicle(ticket1)
π― Step 5: Scalability & Future Enhancements
β
Add multiple floors
β
Support electric vehicle charging
β
Integrate license plate recognition (AI π€)
β
Implement real-time availability tracking using Redis
π Now you have a solid Parking Lot System in Python!
Whatβs next? π₯ Would you like a REST API for this? Drop a comment below! π