1. Spot Allocation by Size: Automatically assign the first available parking spot that fits the vehicle type.
- Motorcycle fits in Small, Medium, or Large spots.
- Car fits in Medium or Large spots.
- Truck only fits in Large spots.
(Rule: SpotType.Size >= VehicleType.Size).
2. Issue Ticket on Entry: When a vehicle enters, generate a ParkingTicket with ticket ID, vehicle info, assigned spot ID, and entry timestamp.
3. Fee Calculation on Exit: Upon departure, calculate the parking fee based on elapsed stay duration and an injected PricingStrategy (e.g., Hourly, Flat, Tiered).
4. Multi-Floor Support: Manage multi-level parking inventory where each floor holds a configurable mix of spot sizes.
5. Lot-Full Rejection: If no compatible spot is available for the incoming vehicle type, reject entry with a lot-full error.
1. Thread Safety / Concurrency: Prevent double-booking (two gates assigning the same spot to two vehicles simultaneously).
2. Extensibility (OCP): Easily add new vehicle types (EV, Bus) or new pricing models (Surge, VIP discount, Daily cap) without modifying existing classes.
3. High Cohesion & Loose Coupling: Separate storage/persistence (Repository), pricing logic (Strategy), and business workflows (Use Cases / ParkingLot).
4. Data Integrity: Ensure spot vacancy state is atomic and synchronized with vehicle entry/exit.
Core Entities:
- Vehicle (Abstract / Interface): Base entity holding licensePlate and VehicleType. Subclasses: Car, Motorcycle, Truck.
- ParkingSpot: Represents an individual space. Attributes: id, spotType, isAvailable, assignedVehicle. Methods: canFit(), assign(), release().
- ParkingFloor: Holds floorId and a list of ParkingSpots. Method: findAvailableSpot(vehicleType).
- ParkingTicket: Records a session. Holds ticketId, vehicle, spot, entryTime, exitTime.
- PricingStrategy (Interface): Computes fees via calculateFee(duration, vehicleType). Implementations: HourlyPricing, FlatRatePricing, TieredPricing.
- ParkingLot: Central coordinator managing floors, active tickets, and entry/exit flows.
Relationships:
- Composition: ParkingLot OWNS ParkingFloors (1-to-N). ParkingFloor OWNS ParkingSpots (1-to-N). (Destroying the lot destroys floors and spots).
- Association: ParkingTicket REFERENCES Vehicle and ParkingSpot (independent lifecycle; discarding a ticket does not delete the spot).
- Strategy Pattern: ParkingLot DELEGATES fee calculation to PricingStrategy interface.
- Inheritance / Polymorphism: Car, Motorcycle, Truck EXTEND Vehicle with fixed size values.
1. Design Trade-offs:
- Explicit Enum Numeric Sizing vs Matrix Map: Used numeric values (1, 2, 3) for SpotType and VehicleType so spotType >= vehicleType replaces complex nested if-else checks. For non-linear compatibility (e.g., handicapped spots), a Map
- Association vs Composition for Tickets: ParkingTicket associates with (references) ParkingSpot rather than owning it, ensuring spot inventory is preserved when tickets are closed upon exit.
- Strategy Pattern vs Hardcoded Pricing: Decoupled pricing logic from ParkingLot to allow runtime algorithm swapping without modifying core workflows.
2. SOLID Principles Compliance:
- Single Responsibility: ParkingSpot handles occupancy; ParkingFloor handles floor lookup; ParkingTicket handles time recording; ParkingLot handles entry/exit coordination.
- Open/Closed: New pricing models (e.g., WeekendPricing, TieredPricing) are added by implementing PricingStrategy without touching ParkingLot.
- Liskov Substitution: All Vehicle subclasses can be passed interchangeably without type casting or instanceof checks.
- Interface Segregation: PricingStrategy defines only calculateFee(), keeping the contract minimal.
- Dependency Inversion: ParkingLot depends on the PricingStrategy abstraction, not concrete implementations.
3. Concurrency & Scalability:
- Race Condition: Multiple entry gates could simultaneously assign the same vacant spot (double-booking).
- Defense: Implemented synchronized locking on ParkingLot.enter() and thread-safe data structures for active tickets.
- Evolution: For high-throughput (airport scale), transition from a global lock to Per-Floor Locking (lock per FloorID) so gates searching different floors run concurrently.
4. Future Improvements:
- EV Charging Spots: ElectricSpot subclass composed with a ChargingStation component and kWh-based pricing.
- Reservation System: Time-window spot reservations with TTL expiration.
- Real-time LED Display Boards: Observer pattern publishing vacancy changes to entry boards.