Grokking the Object Oriented Design Interview
Vote

0% completed

Design a Parking Lot

System Requirements

Use case diagram

Building the design in five stages

Stage 1: the vehicles and the spots

Stage 2: a floor that can find a free spot

Stage 3: the ticket, the rate and the payment

Stage 4: the lot that ties it together

Stage 5: the panels the driver touches

The finished class diagram

The patterns in this design

What we left out, and what to say about it

Let's make an object-oriented design for a multi-floor parking lot.

A parking lot, or car park, is a cleared area set aside for parking vehicles. In countries where most people drive, every city and suburb has them. Shopping malls, sports stadiums, large churches, and similar venues often have parking lots that cover a wide area.

Image

System Requirements

We will focus on the following requirements while designing the parking lot:

  1. The parking lot should have multiple floors where customers can park their cars.

  2. The parking lot should have multiple entry and exit points.

  3. Customers collect a parking ticket at an entry point and pay the parking fee at an exit point on their way out.

  4. Customers can pay at the automated exit panel or to the parking attendant.

  5. Customers can pay by cash or by credit card.

  6. Customers should also be able to pay the parking fee at the customer info portal on each floor. A customer who has paid at the info portal does not pay again at the exit.

  7. The system should not admit more vehicles than the maximum capacity of the parking lot. When the lot is full, the system should show a message on the entrance panel. It should also show one on the parking display board on the ground floor.

  8. Each parking floor will have many parking spots. The system should support multiple types of parking spots, like Compact, Large, Handicapped, and Motorcycle.

  9. The parking lot should have some spots set aside for electric cars. Each of these spots should have an electric panel where customers can pay and charge their vehicles.

  10. The system should support parking for different types of vehicles, like car, truck, van, and motorcycle.

  11. Each parking floor should have a display board that shows the free spots for each spot type.

  12. The system should support a per-hour parking fee model. For example, customers pay $4 for the first hour, $3.5 for the second and third hours, and $2.5 for every hour after that.

Use case diagram

Here are the main actors in our system:

  • Admin: Adds and changes parking floors, parking spots, and the entrance and exit panels. Also adds and removes parking attendants.

  • Customer: Takes a parking ticket and pays for it.

  • Parking attendant: Can do everything a customer can, on the customer's behalf, and can take cash for a ticket.

  • System: Shows messages on the info panels, and assigns a vehicle to a parking spot and removes it again.

Here are the top use cases for the parking lot:

  • Add/Remove/Edit parking floor: Add, remove, or change a parking floor. Each floor can have its own display board that shows free spots.
  • Add/Remove/Edit parking spot: Add, remove, or change a parking spot on a floor.
  • Add/Remove a parking attendant: Add or remove a parking attendant.
  • Take ticket: Give a customer a new parking ticket when they enter the lot.
  • Scan ticket: Scan a ticket to find out the total charge.
  • Credit card payment: Pay the ticket fee with a credit card.
  • Cash payment: Pay the ticket fee with cash.
  • Add/Modify parking rate: Let the admin add or change the hourly parking rate.
Image

Building the design in five stages

The rest of this lesson builds the design one stage at a time. Each stage adds a few classes. Each stage ends with something the system can do that it could not do before.

Use this order in an interview. It gives you a working slice early. If you run out of time, you stop with something that works, not with half a diagram.

StageWhat it addsWhat works after it
1Vehicles and spotsYou can ask whether a vehicle fits a spot
2Floors and the display boardA floor can find a free spot
3Tickets, rates and paymentA stay can be priced and paid for
4The lot itselfA car can enter, park and leave
5Entrance, exit and info panelsThe flow runs through real devices

The code compiles and runs in Python, Java and C++. Read the stages in order and you have the whole program.

Each stage below also adds its classes to one diagram. The classes from earlier stages stay exactly where they were, drawn in gray, so the picture fills in as the build goes on. By the last stage you have seen a reason for every box in the finished diagram.

Stage 1: the vehicles and the spots

Start with the two things the whole product is about. A vehicle arrives, and a spot holds it.

Nothing can be parked yet. What this stage gives you is the rule that decides which spots a given vehicle may use. That rule is the most important part of the design. It lives on Vehicle, so adding a new vehicle type never forces a change in the parking lot.

Enums and constants: the fixed sets the design refers to. An enum is a type with a fixed list of named values, and each set below is one:

Requirements 8 and 10 name the spot types and the vehicle types. Those two requirements produce every class in this stage. The diagram shows two small inheritance trees and one arrow between them. Inheritance means one class is a kind of another and takes on its fields and methods. The arrow says a spot holds at most one vehicle, which is an association written as holds 0..1. An association is a plain link between two classes where neither owns the other. The hollow triangle is inheritance, and it points at the parent. The legend after the diagram shows how to read every arrow used in this lesson.

Image
Image
Python3
Python3
. . . .

ParkingSpot: a spot knows its number, its type, and whether it is free. The five subclasses exist because the class diagram names them. They carry no behavior of their own beyond the type they pass up. Only ElectricSpot adds anything, because it owns the panel a driver uses to charge:

Python3
Python3
. . . .

Vehicle: each vehicle knows which spot types it fits in, best fit first. A motorbike takes a motorbike spot. A truck or a van needs a large spot. An electric car prefers an electric spot and will accept a compact or large one:

Python3
Python3
. . . .

Stage 2: a floor that can find a free spot

Now put the spots somewhere. A floor holds spots and answers one question: is there a free spot that this vehicle fits in?

After this stage the system can find and assign a spot. It can also report how many spots of each type are left.

ParkingDisplayBoard: the board holds a count per spot type. A count is more reliable than tracking one example free spot per type. That example would have to be found again every time that one spot fills:

Requirements 1, 8 and 11 produce the two classes added here. Both new arrows are composition, drawn as a filled diamond. Composition means one class owns another, and the owned part is deleted with its owner. A floor owns its spots and its display board, because deleting the floor deletes them. Compare that with holds from stage 1, where a spot only refers to a vehicle that exists on its own.

Image
Python3
Python3
. . . .

ParkingFloor: one map of every spot, plus an index by type. A separate map per type would mean five maps and a five way branch in every method that touches them. A sixth spot type would then mean editing all of it:

Python3
Python3
. . . .

Stage 3: the ticket, the rate and the payment

A driver needs something that proves when they arrived. The lot needs a way to turn that into money.

The important decision here is that the ticket holds a reference to the actual spot. Without it there is no way to find the vehicle at the exit, or to free its spot. Counting occupied spots is not enough.

ParkingTicket, ParkingRate and Payment: the rate card is requirement 12. Payment covers the cash and card cases from requirement 5:

Requirements 3, 5 and 12 produce the money classes. The ticket points at the vehicle and the spot with plain arrows. Those are associations, not ownership, because a ticket does not own a car. Payment is abstract, with one subclass per way of paying. An abstract class cannot be created on its own; only its subclasses can. This is inheritance that passes the substitution test: both subclasses really can be asked to take money.

Image
Python3
Python3
. . . .

Paying for a parking ticket: here are the steps a customer goes through. Every one of them is covered by the three classes above:

Image

Stage 4: the lot that ties it together

This is the stage where the whole flow works. A car arrives, gets a real spot and a ticket, and later pays and leaves.

Two details are worth saying out loud. The lot is a singleton, a class that allows only one instance, because there is one car park. Handing out a spot has to run one caller at a time. Otherwise two entrances could be given the same spot.

Account, Admin and ParkingAttendant: the people who operate the lot:

Requirement 7 and the actor list produce this stage. The lot owns its floors and its rate card, so the filled diamonds sit at the lot. The people connect with plain arrows. An admin configures the lot and an attendant processes tickets through it, but neither owns anything.

Image
Python3
Python3
. . . .

ParkingLot: it finds a floor with a suitable free spot and issues the ticket. On the way out it prices the stay, and it releases the spot once the ticket is paid:

Python3
Python3
. . . .

Stage 5: the panels the driver touches

The last stage is the devices. None of them hold logic of their own. They call the lot, and that is what keeps the rules in one place.

EntrancePanel, ExitPanel, CustomerInfoPortal and ElectricPanel: the entrance panel prints a ticket. The exit panel scans it and takes payment. The info portal on each floor settles a ticket early, so nothing is owed at the exit. The electric panel bills for charging:

Requirements 2, 4, 6 and 9 produce the panels. The lot owns the entrance and exit panels, so those two arrows are composition. The customer info portal is different. The lot keeps no list of portals, so the portal only refers to the lot, which is a plain association. The electric panel belongs to its electric spot. That is the one composition in the design drawn at a spot.

Image
Python3
Python3
. . . .

The finished class diagram

Now that every class exists, here is the whole model in one picture. It is the same picture the five stages have been filling in, with every class in full color at last. Nothing on it appears here for the first time.

Here are the main classes of our Parking Lot System:

  • ParkingLot: The central part of the organization this software is built for. It has attributes like 'Name' to tell it apart from other parking lots and 'Address' for its location.

  • ParkingFloor: The parking lot has many parking floors.

  • ParkingSpot: Each parking floor has many parking spots. Our system supports five spot types: 1) Handicapped, 2) Compact, 3) Large, 4) Motorcycle, and 5) Electric.

  • Account: There are two types of accounts in the system: one for an Admin, and one for a parking attendant.

  • Parking ticket: This class holds a parking ticket. Customers take a ticket when they enter the parking lot.

  • Vehicle: Vehicles park in parking spots. Our system supports five vehicle types: 1) Car, 2) Truck, 3) Electric, 4) Van and 5) Motorcycle.

  • EntrancePanel and ExitPanel: EntrancePanel prints tickets, and ExitPanel takes payment of the ticket fee.

  • Payment: This class makes payments. The system supports credit card and cash transactions.

  • ParkingRate: This class keeps the hourly parking rates. It gives a dollar amount for each hour. For a two hour ticket, it defines the cost of the first hour and of the second hour.

  • ParkingDisplayBoard: Each parking floor has a display board that shows the free spots for each spot type. This class shows customers the latest count of free spots.

  • ParkingAttendant: This class holds the operations an attendant can perform, which is taking a payment on a customer's behalf. It is an Account, like Admin, because an attendant signs in.

  • CustomerInfoPortal: This class holds the info portal that customers use to pay for a parking ticket. Once paid, the portal updates the ticket to record the payment.

  • ElectricPanel: Customers use the electric panels to pay for and charge their electric vehicles.

Image

The patterns in this design

Singleton. A singleton is a class that allows only one instance. ParkingLot is one, and get_instance is where that is enforced. Expect an interviewer to push back on this pattern harder than on any other. A singleton is a global by another name. It makes two lots impossible to run in one test, and it hides a dependency inside every class that reaches for it.

Nothing else here is a named pattern. Payment with a cash and a card subclass is an abstract base class. The five spot types are plain inheritance. Calling those Strategy would be using the word loosely. Strategy means an object holds a behavior and can swap it for another, and nothing here does.

What we left out, and what to say about it

This design covers the twelve requirements and nothing else. Reservations ahead of arrival, season tickets, number plate recognition and refunds are all absent. That was a decision, not an oversight.

Two places where a reviewer will question the design, and the honest answer to each:

  • The five spot subclasses carry no behavior. They are here because the class diagram names them. A single ParkingSpot with a type field would do the same work. Adding a sixth type would then be one new enum constant.
  • ParkingLot does two jobs. It finds spots and it issues tickets. Those are two reasons to change, so a longer design would split them.

💡 In the interview: build in this order, and say what each stage gives you before you write it. When you reach the ticket, say why it holds a spot rather than a count. That single choice is what makes the exit flow possible. Expect two follow ups. The first is "what if pricing changes", which is the strategy pattern behind ParkingRate. The second is "what if two cars arrive at the same instant", which is why issuing a ticket takes a lock.

Kushak Zohaad Jafry

Kushak Zohaad Jafry

· 7 months ago

Issues I found with this design:

1. Unnecessary Inheritance for ParkingSpot

The code creates separate classes (HandicappedSpot, CompactSpot, LargeSpot, etc.) that literally do nothing except pass an enum to the parent constructor. This violates "composition over inheritance."

java

// Current approach - 5 classes doing the same thing public class CompactSpot extends ParkingSpot { public CompactSpot() { super(ParkingSpotType.COMPACT); } } // Better approach - single class with composition public class ParkingSpot { private String number; private ParkingSpotType type; private boolean free; public ParkingSpot(String number, ParkingSpotType type) { this.number = number; this.type = type; this.free = true;
Show 2 replies
Mithran Daniel

Mithran Daniel

· 2 years ago

Seems like they give working code in free and other paid resources.

Wonder why they did not include method definitions, DB, driver(demo) files, etc

archit chauhan

archit chauhan

· 3 years ago

when there's a change in a parking spot (like a car arriving or leaving), we should make sure that all the electronic display boards on that parking floor show the updated information. So, if a parking spot status changes, all the display boards in that area will know about it and show the correct information to people.

Heinz Yeo

Heinz Yeo

· 3 years ago

This one came up in my interview. Remembering the entities/objects helped with my design, I would say make sure to add cardinality in all the designs. They also wanted to see how my database model worked. They threw curve balls in design to see whether this new entity would relate to the rest of the model. What's the new relationship, how would you adjust to the new cardinality. Hypothetical scenarios, and see where I would change the design.

Something to consider. Having cardinality initially would have made my interview smoother.

Show 1 reply
G

George

· 3 years ago

If you select the JavaScript solution, it jumps back to Python 3 solution.

Reading Progress

0%


Vote for new content

On This Page

System Requirements

Use case diagram

Building the design in five stages

Stage 1: the vehicles and the spots

Stage 2: a floor that can find a free spot

Stage 3: the ticket, the rate and the payment

Stage 4: the lot that ties it together

Stage 5: the panels the driver touches

The finished class diagram

The patterns in this design

What we left out, and what to say about it