Object Oriented Design
Designing a parking lot
Question: The parking lot has multiple levels. Each level has multiple rows of spots. • The parking lot can park motorcycles, cars, and buses. • The parking lot has motorcycle spots, compact spots, and large spots. • A motorcycle can park in any spot. • A car can park in either a single compact spot or a single large spot. • A bus can park in five large spots that are consecutive and within the same row. It cannot park in small spots. You should be able to find a car by the plate and the color.
Understanding responsibilities is key to good object-oriented design. —Martin Fowler
UML Diagram
Python Code:
import enum
class VehicleType(enum.Enum):
undefined = 0
car = 1
bus = 2
motorcycle = 3
class Vehicle:
def __init__(self,color, number):
self.color = color
self.number = number
self.type = VehicleType.undefined
self.parkingSpot = None
def setParkingSpot(self, parkingSpot):
self.parkingSpot = parkingSpot
def getParkingSpot(self):
return self.parkingSpot
def park(self, spot):
raise Exception("Not implemented")
class Car(Vehicle):
def __init__(self, color, number):
super().__init__(color, number)
self.type = VehicleType.car
class MotorCycle(Vehicle):
def __init__(self, color, number):
super().__init__(color, number)
self.type = VehicleType.motorcycle
class ParkingSpot:
def __init__(self, type, parkingNumber, level):
self.type = type
self.parkingNumber = parkingNumber
self.parkingLevel = level
def park(self, vehicle):
self.vehicle = vehicle
def empty(self):
self.vehicle = None
self.parkingLevel.empty(self)
class ParkingLevel:
def __init__(self, levelNumber, parkingSpots):
self.levelNumber = levelNumber
self.parkingSpots = parkingSpots
self.occupied = None
# Map to lookup a vehicle based on the vehicle type
self.vehicleNumberToVehicle = {}
def getParkingSpotWithVehicle(self, vehicle):
return self.vehicleNumberToVehicle[vehicle.number]
def empty(self, vehicle):
self.occupied.remove(vehicle)
self.parkingSpots.append(vehicle)
def park(self, vehicle):
for v in self.parkingSpots:
if v.type == vehicle:
self.occupied = v
v.park(vehicle)
self.vehicleNumberToVehicle[vehicle.number] = vehicle
return v
return None
class parkingLot:
def __init__(self):
self.levels = {}
def addParkingLevel(self, levelNumber, parkingLevel):
self.levels[levelNumber] = parkingLevel
def park(self, vehicle):
for level in self.levels:
isParked = level.park()
if isParked:
return True
return False
def remove(self, vehicle):
for level in self.levels:
spot = level.getParkingSpotWithVehicle(vehicle)
if spot:
spot.empty(vehicle)
return True
return False