Bird
Raised Fist0
Interview Prepoop-design-patternshardAmazonGoogleMicrosoftFlipkartSwiggyRazorpayPhonePeCREDZepto

Design a Parking Lot - LLD with OOP (Classes, Patterns, Extensibility)

Choose your preparation mode3 modes available
▶
Steps
setup

Define the Vehicle class

We start by defining the abstract Vehicle class, which will be the base for all vehicle types in the parking lot.

💡 This step establishes the abstraction for vehicles, allowing extensibility for different vehicle types later.
Line:class Vehicle: def __init__(self, license_plate): self.license_plate = license_plate def get_size(self): pass # Abstract method
💡 Vehicle is an abstract class representing any vehicle, enforcing a common interface.
📊
Design a Parking Lot - LLD with OOP (Classes, Patterns, Extensibility) - Watch the Algorithm Execute, Step by Step
Watching this step-by-step helps you understand how each class and relationship contributes to the overall design, making complex OOP concepts tangible.
Step 1/10
·Active fill★Answer cell
Defines an abstract base class for vehicles to enforce a common interface.
«abstract»Vehicle
+license_plate: string
+get_size()
Demonstrates inheritance and polymorphism for vehicle types.
«abstract»Vehicle
+license_plate: string
+get_size()
Car
+get_size()
Motorcycle
+get_size()
Car ▷ VehicleMotorcycle ▷ Vehicle
Encapsulates parking spot properties and occupancy state.
ParkingSpot
+spot_id: string
+size: float
+occupied: bool
+vehicle: Vehicle
Aggregates parking spots and tracks availability.
ParkingLot
+spots: List[ParkingSpot]
+available_spots: int
Shows aggregation and dynamic spot addition.
ParkingLot
+spots: List[ParkingSpot]
+available_spots: int
+add_parking_spot()
ParkingSpot
+spot_id: string
+size: float
+occupied: bool
+vehicle: Vehicle
ParkingLot ◇ ParkingSpot
Implements search logic to find suitable parking spot.
ParkingLot
+spots: List[ParkingSpot]
+available_spots: int
+find_spot_for_vehicle()
«abstract»Vehicle
+license_plate: string
+get_size()
ParkingSpot
+spot_id: string
+size: float
+occupied: bool
+vehicle: Vehicle
ParkingLot ◇ ParkingSpot
Combines search and update to park vehicles.
ParkingLot
+spots: List[ParkingSpot]
+available_spots: int
+park_vehicle()
+find_spot_for_vehicle()
«abstract»Vehicle
+license_plate: string
+get_size()
ParkingSpot
+spot_id: string
+size: float
+occupied: bool
+vehicle: Vehicle
ParkingLot ◇ ParkingSpot
Handles vehicle removal and spot freeing.
ParkingLot
+spots: List[ParkingSpot]
+available_spots: int
+remove_vehicle()
+park_vehicle()
+find_spot_for_vehicle()
«abstract»Vehicle
+license_plate: string
+get_size()
ParkingSpot
+spot_id: string
+size: float
+occupied: bool
+vehicle: Vehicle
ParkingLot ◇ ParkingSpot
Demonstrates extensibility by adding new vehicle types.
«abstract»Vehicle
+license_plate: string
+get_size()
Truck
+get_size()
Truck ▷ Vehicle
Complete design showing abstraction, inheritance, composition, and encapsulation.
«abstract»Vehicle
+license_plate: string
+get_size()
Car
+get_size()
Motorcycle
+get_size()
Truck
+get_size()
ParkingSpot
+spot_id: string
+size: float
+occupied: bool
+vehicle: Vehicle
ParkingLot
+spots: List[ParkingSpot]
+available_spots: int
+add_parking_spot()
+find_spot_for_vehicle()
+park_vehicle()
+1 more
Car ▷ VehicleMotorcycle ▷ VehicleTruck ▷ VehicleParkingLot ◇ ParkingSpot

Key Takeaways

✓ Abstraction and inheritance allow modeling different vehicle types with a common interface.

This is hard to see from code alone because the polymorphic behavior is implicit; visualization makes it explicit.

✓ Composition is used to aggregate ParkingSpot objects inside ParkingLot, showing real-world containment.

Visualizing relationships clarifies how objects collaborate and depend on each other.

✓ The design supports extensibility by allowing new vehicle types without modifying existing classes.

Seeing the addition of Truck class demonstrates the Open/Closed Principle concretely.

Practice

(1/5)
1. In a large software system, when would applying the Interface Segregation Principle (ISP) be most beneficial?
easy
A. When clients depend on interfaces that contain methods they do not use, causing unnecessary implementation burden.
B. When all clients require the exact same set of methods, so a single fat interface simplifies design.
C. When you want to enforce a strict inheritance hierarchy with minimal interfaces.
D. When you want to reduce the number of interfaces to simplify the codebase.

Solution

  1. Step 1: Understand ISP's goal

    ISP aims to prevent clients from depending on methods they don't use, avoiding fat interfaces that force unnecessary implementations.
  2. Step 2: Analyze options

    When clients depend on interfaces that contain methods they do not use, causing unnecessary implementation burden. correctly identifies the scenario where ISP helps by splitting fat interfaces. When all clients require the exact same set of methods, so a single fat interface simplifies design. describes a scenario where ISP is less needed. When you want to enforce a strict inheritance hierarchy with minimal interfaces. confuses inheritance hierarchy with interface segregation. When you want to reduce the number of interfaces to simplify the codebase. incorrectly assumes fewer interfaces always simplify design, ignoring interface misuse.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    ISP is about splitting interfaces to avoid forcing clients to implement unused methods.
Hint: ISP splits interfaces so clients only depend on what they use.
Common Mistakes:
  • Believing fewer interfaces always mean better design
  • Thinking ISP applies when all clients use all methods
  • Confusing ISP with inheritance hierarchy rules
2. You are designing a system that manages user accounts and sends notification emails. According to the Single Responsibility Principle, how should you organize these responsibilities?
easy
A. Separate user account management and email notification into different classes because each has a different reason to change.
B. Combine user account management and email notification in one class because they are related to users.
C. Put all user-related functionalities, including notifications, into a single class to reduce the number of classes.
D. Create one class for user management and embed email notification logic inside its methods to simplify interactions.

Solution

  1. Step 1: Identify reasons to change

    User account management changes when user data or authentication changes; email notifications change when messaging or delivery requirements change.
  2. Step 2: Apply SRP

    Since these reasons to change differ, they should be separated into different classes to avoid coupling unrelated changes.
  3. Step 3: Evaluate other options

    Options A, C, and D combine responsibilities, increasing coupling and reducing cohesion, violating SRP.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Separate classes for distinct reasons to change -> SRP compliant.
Hint: One class, one reason to change.
Common Mistakes:
  • Assuming related domain means same responsibility.
  • Combining functionalities to reduce class count.
  • Embedding multiple responsibilities for convenience.
3. Which of the following is a common trade-off when using a Facade pattern in a large system?
medium
A. Facade can hide too much complexity, making it hard to access advanced features of subsystems
B. Facade increases coupling between client and subsystems by exposing detailed interfaces
C. Facade always adds significant runtime overhead due to extra method calls
D. Facade requires changing the underlying subsystem interfaces to work properly

Solution

  1. Step 1: Recall Facade's purpose

    Facade simplifies complex subsystems by providing a unified interface.
  2. Step 2: Analyze trade-offs

    While Facade simplifies usage, it can hide advanced features, limiting flexibility.
  3. Step 3: Evaluate other options

    A is incorrect because Facade reduces coupling by hiding subsystem details. C is incorrect; Facade's overhead is minimal. D is wrong; Facade does not require changing subsystems.
  4. Final Answer:

    Option A -> Option A
Hint: Facade hides complexity but may hide power
Common Mistakes:
  • Believing Facade increases coupling instead of reducing it
  • Assuming Facade adds heavy runtime overhead
  • Thinking Facade requires modifying subsystems
4. Which of the following statements about the Liskov Substitution Principle is INCORRECT?
medium
A. A subclass can strengthen preconditions of an inherited method to ensure better input validation.
B. A subclass must not weaken postconditions of an inherited method.
C. Covariance in return types is allowed under LSP.
D. Contravariance in method parameter types is allowed under LSP.

Solution

  1. Step 1: Recall LSP precondition rule

    Subclasses must not strengthen preconditions; they can only maintain or weaken them.
  2. Step 2: Analyze each statement

    A subclass can strengthen preconditions of an inherited method to ensure better input validation. is incorrect because strengthening preconditions breaks substitutability. A subclass must not weaken postconditions of an inherited method. is correct; subclasses can weaken postconditions. Covariance in return types is allowed under LSP. is correct; covariance in return types is allowed. Contravariance in method parameter types is allowed under LSP. is correct; contravariance in parameter types is allowed.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Strengthening preconditions violates LSP.
Hint: Preconditions can only be weakened, not strengthened, in subclasses.
Common Mistakes:
  • Confusing precondition and postcondition rules
  • Believing strengthening preconditions is safe
  • Misunderstanding covariance and contravariance
5. If the Snake and Ladder game is extended to support multiple concurrent games running in parallel, which design consideration is most critical to avoid shared state bugs?
hard
A. Ensuring each game instance has its own independent GameController and Player objects
B. Centralizing player positions in a global data structure accessible by all games
C. Sharing the Dice instance across games to reduce resource usage
D. Using a singleton pattern for the Board class to ensure consistency across games

Solution

  1. Step 1: Singleton Board pattern

    Incorrect: Singleton would cause shared state across games, leading to conflicts.
  2. Step 2: Independent GameController and Player per game

    Correct: Isolates state per game, preventing interference.
  3. Step 3: Sharing Dice instance

    Incorrect: Shared Dice can cause race conditions or inconsistent rolls.
  4. Step 4: Global player positions

    Incorrect: Global state breaks isolation and causes bugs.
  5. Final Answer:

    Option A -> Option A
  6. Quick Check:

    Isolating state per game instance is key for concurrency safety.
Hint: Isolate state per game instance to avoid concurrency bugs [OK]
Common Mistakes:
  • Using singleton for shared components without considering concurrency
  • Sharing mutable objects like Dice across threads
  • Centralizing state globally ignoring isolation
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard