Requirements
Determine the different ways the system will be used. This includes main functions the system needs to perform and who will use it.
- Assign parking spot to vehicle based on availability and size of vehicle
- Calculate fee based on duration parked
Define Core Objects
Based on the requirements and use cases, identify the main objects of the system...
Vehicle
Sedan
Van
Motorcycle
Parking spot
Parking floor
Parking garage
Parking session
Analyze Relationships
Determine how these objects will interact with each other to fulfill the use cases...
There is one parking garage reservation system
The parking garage is comprised of several floors
A floor contains multiple parking spots
A parking spot is occupied (isAvailable: false) if a vehicle is assigned to it.
Only one vehicle may be assigned to a parking spot.
To create a parking session, reservation system checks for available parking spots (isAvailable: true) that match vehicle size
Reservation system calculates fee at conclusion of parking session according to duration parked (stopped_at - created_at)
Establish Hierarchy
Design inheritance trees where applicable to promote code reuse and polymorphism. This step involves identifying common attributes and behaviors that can be abstracted into parent classes...
Sedan, Van, and Motorcycle are subclasses of vehicle
Design Patterns
Consider using design patterns (e.g., Factory, Singleton, Observer, Strategy) that fit the problem...
Parking garage reservation system using singleton design. There is one global object.
Factory class for vehicle types
Define Class Members (write code)
Attributes: For each class, define the attributes (data) it will hold...
Methods: Define the methods (functions) that operate on the attributes. Ensure they align with the object's responsibilities and adhere to the principle of encapsulation.
import math
import datetime
import unittest
class ReservationSystem {
def init(self,pricePerHour,parkingFloors):
self._pricePerHour = pricePerHour
self._parkingFloors = parkingFloors
def createParkingSession(self,vehicle):
"""
Start a parking session
"""
parkingSession = ParkingSession(vehicle.id)
def endParkingSession(self,parkingSession):
"""
End parking session by calculating the fee based on duration
:param parkingSession: the active parking session to end
:return: calculated fee
"""
parkingSession.endParkingSession()
fee = self.calculateFee(parkingSession.duration)
return fee
def calculateFee(duration):
"""
Calculate the parking fee based on duration
:param duration: The duration (in hours) of parking session
:return: Total fee
"""
return duration * self._pricePerHour
def assignSpot(self,parkingSession):
spot = self._getAvailableSpotForVehicle(parkingSession)
spot.reserveSpot(vehicle)
spot._unlock()
return True
def _getAvailableSpotForVehicle(self,parkingSession):
for floor in self._floors:
for spot in floor:
# return first available spot
if spot.IsLocked() == False and spot.isAvailable() == True and spot.getSize() >= parkingSession.getVehicleSize():
spot.lock()
return spot
# if there is no available spot that meets size requirements, notify driver
return False
}
class ParkingFloor:
def init(self,parkingSpots):
self._parkingSpots = parkingSpots
class Vehicle:
def init(self,size):
self._size = size
def createVehicle(type):
if type == "motorcycle":
return Motorcycle()
if type == "sedan":
return Sedan()
if type == "van":
return Van()
class Motorcycle(Vehicle):
def init(self):
super().init(0)
class Sedan(Vehicle):
def init(self):
super().init(1)
class Van(Vehicle):
def init(self):
super().init(2)
class ParkingSession(self,vehicle):
def init(self,vehicle):
self._vehicle = vehicle
self._parkingSpot = None
self._createdAt = datetime.datetime.now()
self._stoppedAt = None
self._duration = None
def endParkingSession(self):
self._stoppedAt = datetime.datetime.now()
self._calculateDuration()
def _calculateDuration(self):
if self._stoppedAt and self._startedAt:
duration = self._stoppedAt - self._startedAt
self._updateDuration(duration)
def _updateDuration(self,duration):
self._duration = duration
class ParkingSpot(size):
def init(self):
self._size = size
self._locked = False
self._isAvailable = True
self._assignedVehicleId = None
def reserve(self,vehicle):
"""
Assigns a parking spot to a vehicle and returns if successful
:param vehicle: The vehicle to assign to the spot
:return: True/False reservation was successful
"""
if self._isLocked():
return False
if self._isAvailable:
self._isAvailable = False
self._assignedVehicleId = vehicle.Id
self._unlock()
return True
return False
def getSize(self):
return self._size
def isAvailable(self):
return self._isAvailable
def _setIsAvailable(self,isAvailable):
self._isAvailable = isAvailable
def _isLocked(self):
return self._locked
def _lock(self):
self._locked = True
def _unlock(self):
self._locked = False
class TestGetAvailableSpot(unittest.TestCase):
def setUp(self):
# initialize array of ParkingFloors, each an array of ParkingSpots
floors = [ParkingFloor([ParkingSpot(0)] * 10 + [ParkingSpot(1)] * 100),
ParkingFloor([ParkingSpot(1)] * 50 + [ParkingSpot(2)] * 50),
ParkingFloor([ParkingSpot(1)] * 50 + [ParkingSpot(2)] * 50)]
self.reservationSystem = ReservationSystem(2.00,floors)
def test_vehicle_size_matches_spot_size(self):
vehicles = [Sedan(), Motorcyle(), Van()]
for vehicle in vehicles:
self.reservationSystem.assignSpot(vehicle)
self.assertEqual(vehicle.getSize(),spot.getSize())
def test_spot_not_available_after_reserved(self):
vehicles = [Sedan(), Motorcyle(), Van()]
for vehicle in vehicles:
self.reservationSystem.assignSpot(vehicle)
self.assertFalse(spot.isAvailable())
if name == "main":
unittest.main()
Adhere to SOLID Guidelines
Check and explain whether your design adheres to solid principles (Ask interviewer what SOLID principle is if you can not recall it.)...
Consider Scalability and Flexibility
Explain how your design can handle changes in scale and whether it would be easily to extend with new functionalities...
Create/Explain your diagram(s)
Try creating a class, flow, state and/or sequence diagram using the diagramming tool. Mermaid flow diagrams can be used to represent system use cases. You can ask the interviewer bot to create a starter diagram if unfamiliar with the tool. Briefly explain your diagrams if necessary...
- ReservationSystem: Manages the entire parking system and contains multiple floors.
- ParkingFloor: Represents a floor in the parking system, which contains multiple parking spots.
- ParkingSpot: Represents a physical spot where a vehicle can park, storing information about its size and availability.
- Vehicle: A base class for different types of vehicles, differentiated by size.
- Sedan, Motorcycle, Van: Specific vehicle types extending the
Vehicleclass with different initial sizes.
Future improvements
Critically examine your design for any flaws or areas for future improvement...