Requirements
Functional Requirements:
- Assign parking spots based on vehicle size, allowing motorcycles to park in small spots, cars in medium spots, and trucks in large spots, with the option to park in larger spots if needed.
- Issue a ParkingTicket upon vehicle entry, which records the vehicle information, assigned parking spot, and entry timestamp.
- Compute the parking fee upon vehicle exit based on the duration of stay and a configurable pricing strategy.
- Handle scenarios where the parking lot is full by rejecting entry and displaying a lot-full indicator to the driver.
- Support multiple floors in the parking lot, with each floor containing a mix of small, medium, and large parking spots.
Non-Functional Requirements:
- extensibility to strategies of finding parking spot using interfaces to adhere to OCP of SOLID principle, eg. 1 strategy class derived from interface could have implementation to find spot based on size, another strategy class could have implementation for custom requirements if they are valid eg. request for larger spot size for a car than the ideal spot size set for the car
- extensibility to price calculation strategies, eg. one class could have strategy based on entry time and exit time, with the multiplier of spot size, another price strategy in future could be dynamic based on peek time etc.
- handling concurrency conditions and ensuring thread safety in case there are multiple entry gates, and multiple vehicles request for a parking spot at same time using locks
Core Objects & Relationships
- Vehicle: containing type, size, id it would be an interface, which different vehicle types can extend like two wheeler, four wheeler, extra large heavy four wheelers
- ticket: containing vehicle id, size and type, entry time, parking spot, floor
- entryGateClass: checks. with parking spot manager to check if a spot is available for requested vehicle which ensuring thread safety
if not available it rejects request
if available, it assigns parking spot , requests parking spot manager to update the status of parking spot occupancy and creates the ticket
- parking spot manager: finds spot, updates spot has aggregate relation with parking lot
- parking Lot: contains state of parking spots i.e. floor, spot its size and whether it is occupied or not: has composition relation with floor, parking spot
- price calculator: interface, which the concrete price calculation strategy classes would inherit
- exit gate: requests parking manager to update parking spot state to available, calculates price using price calculator
APIs & Class Members
- VehicleInterface: id, size
- TwoWheeler, FourWheeler,HeaveFourWheeler derived from VehicleInterface containing size
- Ticket: VehicleType(TwoWheeler, FourWheeler,HeaveFourWheeler), entryTime, priceStrategy
- EntryGate: Instance of ParkingSpotManager, checkSpotAvailabilityMethod, createTicketMethod, updateParkingSpotAvailabilityMethod
- ExitGate: calculatePriceMethod, Instance of ParkingSpotManager, updateParkingSpotAvailabilityMethod
- ParkingSpotManager: lock to ensure thready safety, instance ParkingLot, instance of ParkingSpotFinder, updateParkingSpot method
- ParkingLot: Floor, parking spot list for each supported size
- SpotFinder: instance of ParkingLot to return available spot, and return error if not available
- PriceCalculatorInterface having calculatePriceMethod, PriceCalculateStrategy concrete class will be derived from this and implement own methods to calculatePrice
- ExitGate: has instance of ParkingSpotManager to update parking spot availability state, instanceOfPriceCalculator to calculate price for parking
Deep Dive
SOLID Priniciples: Single responsibility: entry gate only checks for availability through parking spot manager and issuing ticket, parking spot manager checking parking lot class to check and update availability
use of interfaces and derived classes for open close principle in case of parking spot finder and price calculator
Liskov substitution: inherited classes contain all the properties from parent class.
Dependency Inversion: using interface class to create instance instead of concrete derived classes
throwing exceptions if floor or spot being updated is invalid and locks for thread safety