Design Intent
What your code is doing
Factory Pattern
VehicleFactory creates the correct vehicle object from VehicleType, keeping client creation logic clean.
Strategy-Like Floor Design
ParkDesign allows different floor layouts or parking-space generation strategies.
Thread-Safe Allocation
ConcurrentHashMap.replace acts like compare-and-set, so two threads cannot claim the same slot at the same time.
Design Principles
How SOLID appears in this design
Single Responsibility
Vehicle owns vehicle data, Slot owns slot state, and ParkingManager coordinates floors and actions.
Open/Closed
New vehicle types can be added by extending Vehicle and updating the factory/type configuration.
Encapsulation
Slot occupancy is changed through parkAt and vacate, rather than allowing random external mutation.
Concurrency Safety
Parking a slot checks the current value and replaces it atomically only if the expected old value still exists.
Request Flow
How one parking request moves through the classes
Vehicle Creation
Factory creates vehicle from type
The client passes type and plate. The factory returns the correct concrete vehicle.
Vehicle vehicle = VehicleFactory.createVehicle(VehicleType.CAR, "KA-01");Parking Flow
Manager finds floor and updates slot
The manager checks the floor, reads the selected slot, verifies it is free, then atomically assigns the plate.
boolean parked = manager.parkAt(1, 4, vehicle.getPlate());Deep Design Walkthrough
Why each major code decision exists
VehicleType Enum
Define supported vehicle categories in one place
VehicleType acts like a contract between UI, factory, slot configuration, and pricing logic. The parking lot has different slot groups for CAR, BUS, and BIKE, so keeping these values as an enum avoids typo-based bugs from raw strings.
enum VehicleType {
CAR, BUS, BIKE
}
Abstract Vehicle
Use abstraction because all vehicles share state
Your commented code considered an interface first. The final design uses an abstract class because every concrete vehicle needs common data: plate number and vehicle type. This avoids repeating the same fields and getters in Car, Bus, and Bike.
abstract class Vehicle {
private final String plate;
private final VehicleType type;
protected Vehicle(String plate, VehicleType type) {
this.plate = plate;
this.type = type;
}
}
VehicleInfo
Represent slot capability and occupancy separately
VehicleInfo stores the slot type and the currently parked vehicle plate. When value == null, the slot is free. When value contains a plate, it is occupied.
class VehicleInfo {
VehicleType type;
String value;
}
Slot Initialization
Pre-configure slot ranges by vehicle type
The Slot constructor creates a floor layout. In your code, slots 1-19 are for cars, 21-49 are for buses, and 51-99 are for bikes.
public Slot() {
initSlot(1, 20, VehicleType.CAR);
initSlot(21, 50, VehicleType.BUS);
initSlot(51, 100, VehicleType.BIKE);
}
i < en, so initSlot(1, 20) creates slots 1 through 19, not 1 through 20.ConcurrentHashMap
Protect slot state during parallel parking
A real parking lot can have many entry points. Two vehicles may try to park in the same slot at nearly the same time. ConcurrentHashMap gives safe concurrent access to slot state.
private ConcurrentHashMap<Integer, VehicleInfo> slotArray =
new ConcurrentHashMap<>();
HashMap is unsafe when multiple threads read/write together. It can cause inconsistent state.Atomic Allocation
Use replace(old, new) to avoid double booking
The allocation logic first reads the current slot value. It only replaces the slot if the value is still the same object. If another thread already parked there, replace fails.
if (slotArray.replace(slot, current, newInfo)) {
allocated.add(slot);
}
Vacate Logic
Free a slot without changing its vehicle type
When a vehicle exits, the slot should become free but still remain a car/bus/bike slot. That is why vacate creates new VehicleInfo(current.type, null).
VehicleInfo newInfo = new VehicleInfo(current.type, null);
return slotArray.replace(slotNumber, current, newInfo);
ParkingManager
Separate orchestration from raw slot storage
ParkingManager keeps a map of floor number to slot layout. It exposes high-level operations like availability, park, vacate, and print across floors.
private final Map<Integer, Slot> floors = new LinkedHashMap<>();
public void addFloor(int floorNumber, Slot slot) {
floors.put(floorNumber, slot);
}
Code Walkthrough
Explain each important snippet like an interview answer
Vehicle Abstraction
Common data for all vehicles
The abstract class avoids duplication because every vehicle has plate and type.
abstract class Vehicle {
private final String plate;
private final VehicleType type;
}Slot Allocation
Atomic replace prevents double booking
The slot is assigned only if the old free value is still present.
if (map.replace(slotNumber, current, newInfo)) {
return true;
}Manager
Coordinator for floors and parking actions
The manager holds floor-to-slot mapping and exposes methods like park, vacate, and availability.
private final Map<Integer, Slot> floors = new LinkedHashMap<>();
public void addFloor(int floorNumber, Slot slot) {
floors.put(floorNumber, slot);
}Vehicle Factory
Create concrete vehicles at runtime
The caller does not need to directly instantiate Car, Bus, or Bike.
switch (type) {
case CAR: return new Car(noPlate);
case BUS: return new Bus(noPlate);
case BIKE: return new Bike(noPlate);
}Run The Code
Read it here, run it in the embedded Java compiler
Java Source
Compiler-friendly version: no package line, no scanner input, and runnable class is Main.
Embedded Compiler
Copy the Java source on the left and paste it into the compiler. It runs sample parking, availability, and vacate operations automatically.
Interview Ready
Notes For Interview
How to explain the design
This Parking Lot LLD models the system around floors, slots, vehicles, and a parking manager. Vehicles share common data through an abstract `Vehicle` class, while concrete vehicle types like `Car`, `Bus`, and `Bike` extend it. `ParkingManager` coordinates allocation and vacancy, and each floor owns slot state through `Slot`.
Flow Diagram
UML Diagram: IS-A and HAS-A
Core classes
- Vehicle: abstract base class for common vehicle state like plate and type.
- Car, Bus, Bike: concrete vehicle classes with specific `VehicleType`.
- VehicleInfo: stores slot occupancy details.
- Slot: manages slot availability and assignment for a floor.
- ParkingManager: coordinates floors and parking operations.
- VehicleFactory: centralizes object creation for vehicles.
Why these patterns are used
An abstract class is used for `Vehicle` because every vehicle has shared state: plate number and vehicle type. If we used only an interface, each concrete class would repeat the same fields and getters. The abstract class gives inheritance for common data while still allowing concrete classes such as `Car`, `Bike`, and `Bus` to represent specific vehicle categories.
Factory Pattern is used for vehicle creation because object creation should be centralized. The caller can pass a `VehicleType`, and the factory decides whether to create a `Car`, `Bus`, or `Bike`. This makes the creation logic easy to extend when new vehicle types are added.
The design also uses composition heavily. `ParkingManager` has floors, a floor has slots, and a slot has occupancy information. This HAS-A structure is better than forcing inheritance between unrelated concepts.
Algorithm explanation
The parking allocation algorithm scans floors and slots to find the first compatible free slot for the requested vehicle type. Once a candidate slot is found, it tries to reserve the slot. The important detail is that reservation should be atomic so two parallel entry-gate requests cannot assign the same slot.
In the current design, `ConcurrentHashMap` and atomic replacement help protect slot state. The algorithm is essentially a first-fit allocation strategy. It is simple and predictable, but not always optimal. In a production system, this could be replaced by a strategy such as nearest-slot, lowest-floor-first, gate-aware allocation, or reserved-slot allocation.
Strong interview answer
"I would separate parking orchestration from slot state. The manager scans floors and delegates actual slot assignment to the floor's slot container. Vehicles use inheritance because they share common state, and atomic slot updates prevent two requests from booking the same slot."
Production improvements
- Add ticket, payment, pricing strategy, entry gate, and exit gate classes.
- Support nearest-slot or best-slot allocation strategy.
- Persist active tickets and parking history.
- Add reservations, electric charging slots, and disabled-accessible slots.
- Use distributed locks if multiple entry gates run on different machines.
Weakness to mention
The demo captures slot allocation, but a full parking lot design should model tickets, gates, pricing, payment, time-based fee calculation, and persistence.