πŸš— Designing a Scalable Parking Lot System: Low-Level Design (LLD) Step by Step

harshit_barde
3 min read5 days ago

--

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

  1. βœ… Vehicles can enter and exit the parking lot.
  2. βœ… The system should assign an available parking spot.
  3. βœ… Different vehicle types (bike, car, truck) need different-sized spots.
  4. βœ… Keep track of occupied and free spots.
  5. βœ… 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 = 3
class 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 duration
payment_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! πŸ‘‡

--

--

harshit_barde
harshit_barde

Written by harshit_barde

Passionate data engineer and vacationer, exploring realms of travel and technology. Every adventure fuels my soul and sparks creativity.

No responses yet