Chaturmind
LearnDSASystem DesignDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
Chaturmind
← Low-Level Design & Design Patterns

OOP Fundamentals & SOLID Principles

  • Object-Oriented Design Refresher
  • Single Responsibility & Open/Closed
  • Liskov Substitution & Interface Segregation
  • Dependency Inversion

Creational Design Patterns

  • Singleton Pattern
  • Factory & Abstract Factory
  • Builder Pattern
  • Prototype Pattern

Structural Design Patterns

  • Adapter & Facade
  • Decorator Pattern
  • Composite & Proxy
  • Bridge & Flyweight

Behavioral Design Patterns

  • Strategy Pattern
  • Observer Pattern
  • Command Pattern
  • Template Method
  • State Pattern
  • Chain of Responsibility
  • Iterator & Mediator
  • Visitor Pattern

Machine Coding Exercises

  • Parking Lot — Requirements & Class Design
  • Parking Lot — Implementation
  • Elevator System — Requirements & Class Design
  • Elevator System — Implementation & Scheduling
  • Library Management System
  • Tic-Tac-Toe / Board Game Design
  • Chess Engine Design
  • Vending Machine Design
  • ATM System Design
  • In-Memory Rate Limiter
  • Thread-Safe LRU Cache
  • Connection Pool Design
  • Producer-Consumer Class Design
  • Movie Ticket Booking System
  • Hotel Reservation System
  • Airline Booking / Seat Selection System
  • Splitwise / Expense Sharing System
  • Design a Logging Framework
  • Design a Notification/Observer-Based Pub-Sub
  • Design a Cache with Pluggable Eviction Policy
  • Design Snake and Ladder
  • Design a Card Game Framework
  • Design an Inventory Management System
  • Restaurant Management System
  • Food Delivery Order Matching
  • Design a Shopping Cart & Checkout Flow
  • Design a Recommendation Engine
  • Design a Job Scheduler
  • Design a Circuit Breaker
  • Design a Distributed ID Generator
  • Design a Pub-Sub Message Broker
  • Design Twitter/X
  • Multi-Pattern Problem: Design a Ride Booking Class Model
  • Multi-Pattern Problem: Design a Food Ordering Class Model
  • Design an Authentication/Authorization Module
  • Design a Form/Survey Builder
  • Design a Meeting Room / Calendar Booking System
  • Design a Search/Filter Engine for an E-Commerce Catalog
  • Design a Voting/Polling System
  • Design a Retry Mechanism with Backoff
  • Design a Health Check Aggregator
  • Design a Feature Flag System
  • Design a Config Management Client
  • Design a Leader Election Algorithm
  • Design a Distributed Counter
  • Design a Bloom Filter
  • Design a Consistent Hashing Ring
  • Design a Distributed Tracing Library
  • Design a Metrics Collection Library
  • Design an Audit Logging Framework
  • Design a Plugin/Extension System
  • Design a Workflow Engine
  • Multi-Pattern Capstone: Design a Food Delivery App
HomeLearnSystem DesignLow-Level Design & Design PatternsMachine Coding Exercises
✓ FreeIntermediate· 8 min read

Parking Lot — Requirements & Class Design

A full machine-coding walkthrough, part 1: scoping a parking lot system and translating it into a first-pass class diagram using the nouns-and-verbs technique.

Published September 23, 2026


Parking Lot — Requirements & Class Design

"Design a parking lot" is one of the most common LLD prompts precisely because it's deceptively simple — it rewards candidates who scope it carefully and punishes anyone who starts coding immediately.

Step 1: clarify scope before anything else

Asking these out loud (see Object-Oriented Design Refresher for why this matters generally) turns a vague prompt into a concrete one:

  • Multiple floors, or just one? → assume multiple, since it's the more general case and barely harder.
  • Multiple spot types? → assume compact, large, and handicap spots, each fitting different vehicle sizes.
  • Entry/exit gates → assume multiple entry points issuing tickets, multiple exit points processing payment.
  • Payment → assume a fee calculated by duration and vehicle type, paid at exit.

Stating these assumptions explicitly (rather than silently picking one and hoping it matches the interviewer's expectation) is itself part of what's being evaluated.

Step 2: nouns and verbs → candidate classes and methods

Applying the technique from the OOP Refresher directly to this prompt:

Nouns (candidate classes): ParkingLot, Floor, ParkingSpot, Vehicle, Ticket, Gate (Entry/Exit). Verbs (candidate methods): parkVehicle, unparkVehicle, findAvailableSpot, issueTicket, calculateFee, isFull.

Step 3: the class diagram — composition first

ParkingLot
  └── has many → Floor
                   └── has many → ParkingSpot

Vehicle ←→ Ticket (a ticket references the vehicle and the spot it occupies)
enum VehicleType { MOTORCYCLE, CAR, TRUCK }
enum SpotType { COMPACT, LARGE, HANDICAP }

abstract class Vehicle {
    private final String licensePlate;
    private final VehicleType type;
    Vehicle(String licensePlate, VehicleType type) {
        this.licensePlate = licensePlate; this.type = type;
    }
    VehicleType getType() { return type; }
}
class Car extends Vehicle { Car(String plate) { super(plate, VehicleType.CAR); } }
class Motorcycle extends Vehicle { Motorcycle(String plate) { super(plate, VehicleType.MOTORCYCLE); } }
class Truck extends Vehicle { Truck(String plate) { super(plate, VehicleType.TRUCK); } }

class ParkingSpot {
    private final String id;
    private final SpotType type;
    private boolean occupied = false;
    private Vehicle parkedVehicle;

    ParkingSpot(String id, SpotType type) { this.id = id; this.type = type; }

    boolean canFit(Vehicle vehicle) {
        // a compact spot can't fit a truck; a large spot can fit anything smaller too
        return switch (vehicle.getType()) {
            case MOTORCYCLE -> true; // fits any spot type
            case CAR -> type == SpotType.COMPACT || type == SpotType.LARGE;
            case TRUCK -> type == SpotType.LARGE;
        };
    }

    void park(Vehicle vehicle) { this.parkedVehicle = vehicle; this.occupied = true; }
    void vacate() { this.parkedVehicle = null; this.occupied = false; }
    boolean isOccupied() { return occupied; }
}

class Floor {
    private final int floorNumber;
    private final List<ParkingSpot> spots;

    Floor(int floorNumber, List<ParkingSpot> spots) { this.floorNumber = floorNumber; this.spots = spots; }

    Optional<ParkingSpot> findAvailableSpot(Vehicle vehicle) {
        return spots.stream()
            .filter(s -> !s.isOccupied() && s.canFit(vehicle))
            .findFirst();
    }
}

class Ticket {
    private final String id;
    private final Vehicle vehicle;
    private final ParkingSpot spot;
    private final Instant entryTime;

    Ticket(String id, Vehicle vehicle, ParkingSpot spot) {
        this.id = id; this.vehicle = vehicle; this.spot = spot; this.entryTime = Instant.now();
    }
    Instant getEntryTime() { return entryTime; }
    ParkingSpot getSpot() { return spot; }
}

class ParkingLot {
    private final List<Floor> floors;

    ParkingLot(List<Floor> floors) { this.floors = floors; }

    Optional<Ticket> parkVehicle(Vehicle vehicle) {
        for (Floor floor : floors) {
            Optional<ParkingSpot> spot = floor.findAvailableSpot(vehicle);
            if (spot.isPresent()) {
                spot.get().park(vehicle);
                return Optional.of(new Ticket(UUID.randomUUID().toString(), vehicle, spot.get()));
            }
        }
        return Optional.empty(); // lot is full for this vehicle type
    }
}

Why composition, drawn before any code

ParkingLot has Floors, each has ParkingSpots — this is composition (see the OOP Refresher's composition-vs-inheritance section), not inheritance: a Floor isn't a kind of ParkingLot, it's a part of one. Drawing this relationship before writing a single line of code is what prevents a common beginner mistake in this exact prompt — modeling Floor extends ParkingLot or similar, which would be structurally wrong (a floor isn't a specialization of a parking lot, it's a component of one).

What Part 2 builds on top of this

This lesson deliberately stops at structure — canFit() returning a boolean and parkVehicle() finding the first available spot are the simplest possible implementations. Parking Lot — Implementation covers making spot selection smarter (a Strategy-pattern-based allocation policy), fee calculation as its own swappable strategy, and the concurrency question every interviewer eventually asks: what happens when two vehicles request the same spot at the same time.

Follow-up questions this topic invites — and their answers

Q: Why is Vehicle abstract with subclasses, instead of just a VehicleType enum field on a single Vehicle class? A: Either works for this level of complexity — the abstract-class version scales better if different vehicle types eventually need genuinely different behavior (not just a different type label), while a single class with an enum field is simpler when the difference truly is just a classification. Stating this tradeoff explicitly is a stronger answer than picking one silently.

Q: Why does ParkingSpot.canFit() live on ParkingSpot rather than on Vehicle or ParkingLot? A: It's a judgment call, but placing it on ParkingSpot keeps the 'can this spot accept this vehicle' rule colocated with the spot's own type — an alternative that's equally defensible is a separate SpotAllocationStrategy (foreshadowing Part 2), which becomes preferable once allocation policy needs to vary independently of the spot's static type.

Q: What's missing from this design that a real system would need? A: Payment processing, a way to look up an active ticket by vehicle/spot at exit time (this design has no reverse-lookup structure yet), and handling a full lot gracefully at the gate rather than just returning an empty Optional — all reasonable follow-ups an interviewer might probe if time allows.

Previous

Visitor Pattern

Next

Parking Lot — Implementation

AI Tutor

Lesson: Parking Lot — Requirements & Class Design

Quick actions

AI responses can be inaccurate. Verify critical information.