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· 7 min read

Elevator System — Requirements & Class Design

Part 1 of a full machine-coding walkthrough: scoping an elevator system, identifying core classes, and modeling the elevator's behavior as an explicit state machine.

Published September 23, 2026


Elevator System — Requirements & Class Design

Step 1: clarify scope

  • How many elevators, how many floors? → assume multiple elevators (a bank of elevators) serving N floors — the multi-elevator case is the more general and more interesting one.
  • Request types? → two distinct kinds: an internal request (a button pressed inside a specific elevator, targeting a floor) and an external request (an up/down button pressed on a floor, not tied to any specific elevator yet).
  • Scheduling → out of scope for this lesson (covered in Part 2) — for now, just model the requests and the elevator's own state correctly.

Step 2: nouns and verbs

Nouns: ElevatorSystem, Elevator, Request (internal/external), Dispatcher/Controller. Verbs: requestElevator, pressFloorButton, move, openDoor, closeDoor, dispatch.

Step 3: the elevator's state machine

An elevator's behavior at any moment is entirely determined by its current state — this is a direct application of State Pattern, and modeling it explicitly (rather than a tangle of booleans like isMoving, isDoorOpen, direction) is what separates a clean design from a fragile one.

IDLE ──(request received)──▶ MOVING_UP / MOVING_DOWN
MOVING_UP/DOWN ──(reached a requested floor)──▶ DOOR_OPEN
DOOR_OPEN ──(timeout / button)──▶ IDLE (no more requests) or MOVING_UP/DOWN (more requests queued)
enum Direction { UP, DOWN, IDLE }

interface ElevatorState {
    void handle(Elevator elevator);
}

class IdleState implements ElevatorState {
    public void handle(Elevator elevator) {
        if (elevator.hasPendingRequests()) {
            elevator.setState(elevator.nextTargetIsAbove() ? new MovingUpState() : new MovingDownState());
        }
    }
}
class MovingUpState implements ElevatorState {
    public void handle(Elevator elevator) {
        elevator.moveOneFloorUp();
        if (elevator.hasRequestAtCurrentFloor()) elevator.setState(new DoorOpenState());
    }
}
class MovingDownState implements ElevatorState {
    public void handle(Elevator elevator) {
        elevator.moveOneFloorDown();
        if (elevator.hasRequestAtCurrentFloor()) elevator.setState(new DoorOpenState());
    }
}
class DoorOpenState implements ElevatorState {
    public void handle(Elevator elevator) {
        elevator.clearRequestAtCurrentFloor();
        elevator.setState(new IdleState()); // IdleState.handle() immediately re-evaluates for remaining requests
    }
}
class Elevator {
    private final int id;
    private int currentFloor = 0;
    private ElevatorState state = new IdleState();
    private final TreeSet<Integer> upRequests = new TreeSet<>();   // sorted — nearest requests first
    private final TreeSet<Integer> downRequests = new TreeSet<>(Comparator.reverseOrder());

    void setState(ElevatorState state) { this.state = state; }
    void step() { state.handle(this); } // called repeatedly, e.g. by a scheduler tick

    void addInternalRequest(int floor) {
        if (floor > currentFloor) upRequests.add(floor); else if (floor < currentFloor) downRequests.add(floor);
    }
    boolean hasPendingRequests() { return !upRequests.isEmpty() || !downRequests.isEmpty(); }
    boolean nextTargetIsAbove() { return !upRequests.isEmpty(); }
    void moveOneFloorUp() { currentFloor++; }
    void moveOneFloorDown() { currentFloor--; }
    boolean hasRequestAtCurrentFloor() { return upRequests.contains(currentFloor) || downRequests.contains(currentFloor); }
    void clearRequestAtCurrentFloor() { upRequests.remove(currentFloor); downRequests.remove(currentFloor); }
}

Why State pattern specifically, not a boolean/enum switch

Per State Pattern's own guidance on when the pattern earns its complexity: an elevator's states have meaningfully different behavior (moving up computes a different next action than door-open does), not just a different label — and the transition logic itself varies enough per state (idle re-evaluates whether to move at all; door-open unconditionally returns to idle) that a single switch on an enum would accumulate real branching complexity. This is close to the strongest possible case for full State-pattern classes, not the traffic-light-simple case where an enum+switch would suffice.

The Dispatcher/Controller — placeholder for Part 2

class ElevatorSystem {
    private final List<Elevator> elevators;
    ElevatorSystem(List<Elevator> elevators) { this.elevators = elevators; }

    void requestElevator(int floor, Direction direction) {
        // Part 2: which elevator answers this call? Left unimplemented here deliberately.
    }
}

This lesson deliberately leaves requestElevator's dispatch logic as a stub — Elevator System — Implementation & Scheduling is entirely about that decision: which of several elevators should answer an external call, and how in-progress requests merge with new ones.

Follow-up questions this topic invites — and their answers

Q: Why TreeSet for pending requests instead of a plain List? A: A sorted set keeps the nearest pending floor immediately accessible (first()/last()) without a linear scan or a separate sort step every time a new request is added — upRequests sorted ascending naturally gives 'nearest floor above, going up' as the next stop, and downRequests sorted descending gives the same for going down.

Q: What happens if a new internal request arrives for a floor the elevator already passed while moving up? A: With the split-by-direction TreeSet design, a floor below the current position moving up would go into downRequests, not upRequests — meaning the elevator would need to finish its current up-direction sweep before addressing it. This mirrors how real elevators behave (see the SCAN algorithm in Part 2) rather than immediately reversing direction for every new request, which would be inefficient and disorienting for other passengers already inside.

Q: Is DoorOpenState really necessary as its own state, or could 'stopping at a floor' just be an action inside MovingUpState/MovingDownState? A: Making it explicit is what allows door-related concerns (a timeout before auto-closing, an obstruction sensor keeping it open, a manual close button) to be modeled cleanly later without those concerns bleeding into the movement states — exactly the kind of 'meaningfully different behavior per state' that justifies State pattern's structure over a simpler boolean flag.

Previous

Parking Lot — Implementation

Next

Elevator System — Implementation & Scheduling

AI Tutor

Lesson: Elevator System — Requirements & Class Design

Quick actions

AI responses can be inaccurate. Verify critical information.