Home/Learn/Low Level Design/Design an Elevator System

Design an Elevator System

Intermediate
LLD Interview Problems
Java Source Code

Model a multi-elevator system with a controller that schedules requests using the LOOK algorithm and tracks each elevator as a state machine.

Overview

An elevator system consists of one or more Elevator cars managed by an ElevatorController. Each elevator operates as a state machine with states Idle, MovingUp, MovingDown, and DoorsOpen. Requests originate either externally (hall button on a floor) or internally (panel inside the car). The LOOK scheduling algorithm minimises travel distance by servicing all requests in the current direction before reversing. Observer pattern notifies door-sensor listeners when doors open or close. This problem tests State, Strategy, and Observer pattern knowledge under a timed interview scenario.

Requirements Analysis

Functional: handle external hall requests (floor + direction) and internal cabin requests (destination floor), move elevator to correct floor, open/close doors, dispatch nearest idle elevator. Non-functional: extensible scheduling (swap LOOK for FCFS without changing Elevator), thread-safe request queue, real-time door-sensor events via Observer.

Requirements
// Entities : ElevatorSystem, Elevator, ElevatorController, Request, Direction, ElevatorState
// Patterns : State (elevator lifecycle), Strategy (LOOK scheduler), Observer (door sensors)

Core Classes & Relationships

Direction enum has UP, DOWN, IDLE. ElevatorState is an interface with handleRequest() and getStateName(). Concrete states: IdleState, MovingUpState, MovingDownState, DoorsOpenState. Request is a value object holding floor, direction, and type (INTERNAL/EXTERNAL). SchedulingStrategy interface is implemented by LookScheduler.

Java — enums & interfaces
public enum Direction { UP, DOWN, IDLE }
public enum RequestType { INTERNAL, EXTERNAL }

public record Request(int floor, Direction direction, RequestType type) {}

public interface ElevatorState {
    void handleRequest(Elevator elevator, Request request);
    String getStateName();
}

public interface SchedulingStrategy {
    Elevator selectElevator(List<Elevator> elevators, Request request);
}

public interface DoorSensorListener {
    void onDoorsOpened(int floor);
    void onDoorsClosed(int floor);
}

Java Implementation

Elevator holds its current floor, direction, state, and a sorted destination set. transitionTo() swaps the state object. ElevatorController receives external requests and delegates to the SchedulingStrategy to pick an elevator. LookScheduler picks the nearest elevator moving in the same direction, or the nearest idle one.

Java — core classes
public class Elevator {
    private int currentFloor = 0;
    private Direction direction = Direction.IDLE;
    private ElevatorState state;
    private final TreeSet<Integer> destinations = new TreeSet<>();
    private final List<DoorSensorListener> listeners = new ArrayList<>();

    public Elevator() { this.state = new IdleState(); }

    public void addDestination(int floor) { destinations.add(floor); }
    public void transitionTo(ElevatorState newState) { this.state = newState; }
    public void addListener(DoorSensorListener l) { listeners.add(l); }

    public void step() {   // called by a scheduler tick
        if (destinations.isEmpty()) { direction = Direction.IDLE; return; }
        int next = direction == Direction.DOWN ? destinations.first() : destinations.last();
        if (next > currentFloor)      direction = Direction.UP;
        else if (next < currentFloor) direction = Direction.DOWN;
        currentFloor += (direction == Direction.UP ? 1 : -1);
        if (currentFloor == next) {
            destinations.remove(next);
            listeners.forEach(l -> l.onDoorsOpened(currentFloor));
            listeners.forEach(l -> l.onDoorsClosed(currentFloor));
        }
    }

    public int getCurrentFloor() { return currentFloor; }
    public Direction getDirection() { return direction; }
}

// ── Concrete states ───────────────────────────────────────────────
class IdleState implements ElevatorState {
    @Override public void handleRequest(Elevator e, Request r) {
        e.addDestination(r.floor());
        e.transitionTo(r.floor() > e.getCurrentFloor() ? new MovingUpState() : new MovingDownState());
    }
    @Override public String getStateName() { return "IDLE"; }
}

class MovingUpState implements ElevatorState {
    @Override public void handleRequest(Elevator e, Request r) {
        if (r.floor() > e.getCurrentFloor()) e.addDestination(r.floor());
    }
    @Override public String getStateName() { return "MOVING_UP"; }
}

class MovingDownState implements ElevatorState {
    @Override public void handleRequest(Elevator e, Request r) {
        if (r.floor() < e.getCurrentFloor()) e.addDestination(r.floor());
    }
    @Override public String getStateName() { return "MOVING_DOWN"; }
}

// ── Controller ────────────────────────────────────────────────────
public class ElevatorController {
    private final List<Elevator> elevators;
    private final SchedulingStrategy scheduler;

    public ElevatorController(List<Elevator> elevators, SchedulingStrategy scheduler) {
        this.elevators = elevators;
        this.scheduler = scheduler;
    }

    public void processRequest(Request request) {
        Elevator chosen = scheduler.selectElevator(elevators, request);
        chosen.addDestination(request.floor());
    }
}

Key Points to Remember

  • 1State pattern encapsulates per-state behaviour: MovingUpState silently drops downward requests, IdleState accepts any.
  • 2LOOK algorithm outperforms FCFS by batching same-direction requests, cutting average wait time significantly.
  • 3Observer (DoorSensorListener) decouples door-open events from safety systems, display screens, and logging.
  • 4Using a TreeSet for destinations gives O(log n) add and O(1) min/max access, perfect for LOOK direction checks.

Interview Questions

Sign in to ask Aria
1

How would you implement the LOOK disk-scheduling algorithm for elevator floor selection?

HardGoogle
2

How does the State pattern help manage elevator lifecycle transitions compared to if-else chains?

MediumAmazon
3

How would you scale this design to handle 50 elevators across a skyscraper with real-time occupancy data?

HardMicrosoft

Ask Aria about Design an Elevator System

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…