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): parkingSession = ParkingSession(vehicle.id) parkingSession.assignSpot(vehicle) def endParkingSession(self,parkingSession): parkingSession.endParkingSession() self.calculateFee(parkingSession.duration) def calculateFee(duration): return duration * self._pricePerHour 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.size >= parkingSession.vehicle.size: spot.lock() return spot # if there is no available spot that meets size requirements, notify driver return False def assignSpot(self,parkingSession): spot = self.getAvailableSpotForVehicle(parkingSession) spot.reserveSpot(vehicle) spot.unlock() return True } 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 isLocked(self): return self._locked def lock(self): self._locked = True def unlock(self): self._locked = False def reserve(self,vehicle): if self.isLocked(): return False self._isAvailable = False self.assignedVehicleId = vehicle.Id self.unlock() return True def isAvailable(self): return self._isAvailable() def main(): initialize array of ParkingFloors, each an array of ParkingSpots floors = [ParkingFloor([ParkingSpot(0)] * 10 + [ParkingSpot(1)] * 100), ParkingFloor([ParkingSpot(1) * 50 ParkingSpot(2) * 50]) * 2] reservationSystem = ReservationSystem(2.00,floors) class TestGetAvailableSpot(unittest.TestCase): def testGetAvailableSpot(self): vehicles = [Sedan(), Motorcyle(), Van()] for vehicle in vehicles: spot = getAvailableSpotForVehicle(vehicle) self.assertEqual(vehicle.size,spot.size) self.assertFalse(spot.isAvailable())





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 Vehicle class with different initial sizes.




Future improvements

Critically examine your design for any flaws or areas for future improvement...