Skip to main content

Design an Elevator/Lift system

Problem Statement

Design an elevator system for a multi floor building. The design should be able to handle elevator requests from different floors, move elevators in the correct direction, and stop at requested floors efficiently. The elevator should also maintain its current state such as direction, floor position, and movement status.


Functional Requirements

  • The design should support multiple elevators
  • Users should be able to request an elevator from any floor
  • Users inside the elevator should be able to select destination floors
  • The elevator should move in upward and downward directions
  • The design should track the current floor of each elevator
  • The design should maintain the current state of the elevator such as moving, idle, or stopped
  • The nearest available elevator should handle incoming requests
  • The elevator should stop at all requested floors while moving in the same direction

Objects Required

  • Elevator
  • ElevatorController
  • ElevatorRequest
  • Direction
  • ElevatorState
  • Building
  • Floor

Direction Enum


public enum Direction {
    UP,
    DOWN
}

The Direction enum represents the movement direction of an elevator. Instead of using strings like "up" or "down", the enum restricts the allowed values and makes comparisons cleaner inside the elevator logic.


ElevatorState Enum


public enum ElevatorState {
    MOVING,
    IDLE,
    STOPPED
}

The ElevatorState enum keeps track of what the elevator is currently doing. An elevator can either be moving, idle while waiting for requests, or temporarily stopped at a floor.


ElevatorRequest Class

The ElevatorRequest class represents a request generated by a user.


public class ElevatorRequest {

    private int sourceFloor;
    private int destinationFloor;
    private Direction direction;

    public ElevatorRequest(int sourceFloor, int destinationFloor, Direction direction) {
        this.sourceFloor = sourceFloor;
        this.destinationFloor = destinationFloor;
        this.direction = direction;
    }

    public int getSourceFloor() {
        return sourceFloor;
    }

    public int getDestinationFloor() {
        return destinationFloor;
    }

    public Direction getDirection() {
        return direction;
    }
}

The constructor captures the source floor, destination floor, and direction at the moment the request is created.

The getter methods provide controlled access to request details. These methods are mainly used by the controller and elevator while deciding which request should be processed next.


Elevator Class

The Elevator class models a single elevator and contains the core movement logic.


import java.util.*;

public class Elevator {

    private int id;
    private int currentFloor;
    private Direction direction;
    private ElevatorState state;
    private Queue<Integer> floorRequests;

    public Elevator(int id) {
        this.id = id;
        this.currentFloor = 0;
        this.state = ElevatorState.IDLE;
        this.floorRequests = new LinkedList<>();
    }

    public void addFloorRequest(int floor) {
        floorRequests.offer(floor);
    }

    public void move() {

        while (!floorRequests.isEmpty()) {

            int destinationFloor = floorRequests.poll();

            if (destinationFloor > currentFloor) {
                direction = Direction.UP;

                while (currentFloor < destinationFloor) {
                    currentFloor++;
                    System.out.println("Elevator moving up to floor " + currentFloor);
                }

            } else if (destinationFloor < currentFloor) {

                direction = Direction.DOWN;

                while (currentFloor > destinationFloor) {
                    currentFloor--;
                    System.out.println("Elevator moving down to floor " + currentFloor);
                }
            }

            state = ElevatorState.STOPPED;
            System.out.println("Elevator stopped at floor " + currentFloor);
        }

        state = ElevatorState.IDLE;
    }
}

The constructor initializes the elevator with an id, starting floor, and an empty request queue. The elevator starts in the IDLE state because it is not handling any requests initially.

The addFloorRequest() method adds a floor number to the queue. Requests are stored so that the elevator can process them one after another instead of immediately jumping to a floor.

The move() method contains the actual movement logic. It continuously processes pending floor requests until the queue becomes empty.

When the destination floor is greater than the current floor, the elevator direction is set to UP. The elevator then moves floor by floor until it reaches the destination.

If the destination floor is smaller than the current floor, the direction changes to DOWN and the elevator moves downward in a similar way.

Once the elevator reaches a requested floor, its state changes to STOPPED. After all requests are completed, the elevator becomes IDLE again.


ElevatorController Class

The ElevatorController class is responsible for assigning requests to elevators.


import java.util.*;

public class ElevatorController {

    private List<Elevator> elevators;

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

    public void submitRequest(ElevatorRequest request) {

        Elevator selectedElevator = elevators.get(0);

        selectedElevator.addFloorRequest(request.getSourceFloor());
        selectedElevator.addFloorRequest(request.getDestinationFloor());

        selectedElevator.move();
    }
}

The constructor initializes the controller with a list of elevators available in the building.

The submitRequest() method receives a request and assigns it to an elevator. In this simplified design, the first elevator is selected directly. In a real production level design, this logic can be improved further by selecting the nearest idle elevator or the elevator already moving in the same direction.

After selecting an elevator, the controller adds both the pickup floor and destination floor to the request queue and triggers movement.


Building Class

The Building class acts as a wrapper around the elevators and controller.


import java.util.*;

public class Building {

    private List<Floor> floors;
    private ElevatorController controller;

    public Building(List<Floor> floors, ElevatorController controller) {
        this.floors = floors;
        this.controller = controller;
    }
}

The constructor associates the building with available floors and the elevator controller. This keeps all major components grouped together in one place.


Floor Class


public class Floor {

    private int floorNumber;

    public Floor(int floorNumber) {
        this.floorNumber = floorNumber;
    }

    public int getFloorNumber() {
        return floorNumber;
    }
}

The Floor class represents an individual floor in the building.

The constructor initializes the floor number, and the getFloorNumber() method provides access to it whenever required by other classes.


Main Class

The Main class is used to simulate the elevator flow by creating elevators, floors, and requests.


import java.util.*;

public class Main {

    public static void main(String[] args) {

        Elevator elevator1 = new Elevator(1);
        Elevator elevator2 = new Elevator(2);

        List<Elevator> elevators = Arrays.asList(elevator1, elevator2);

        ElevatorController controller =
                new ElevatorController(elevators);

        List<Floor> floors = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            floors.add(new Floor(i));
        }

        Building building = new Building(floors, controller);

        ElevatorRequest request =
                new ElevatorRequest(2, 7, Direction.UP);

        controller.submitRequest(request);
    }
}

The main() method starts by creating elevators and storing them inside a list.

The ElevatorController is then initialized with the available elevators so that requests can be assigned later.

A list of floors is created for the building using a simple loop.

Finally, an elevator request is created from floor 2 to floor 7, and the controller processes the request by assigning an elevator and moving it to the requested floors.

Class Diagram

Elevatorid : intcurrentFloor : intdirection : Directionstate : ElevatorStatefloorRequests : Queue<Integer>addFloorRequest(floor : int) : voidmove() : voidDirectionUPDOWNElevatorStateMOVINGIDLESTOPPEDElevatorRequestsourceFloor : intdestinationFloor : intdirection : DirectiongetSourceFloor() : intgetDestinationFloor() : intgetDirection() : DirectionElevatorControllerelevators : List<Elevator>submitRequest(request : ElevatorRequest) : voidBuildingfloors : List<Floor>controller : ElevatorControllerFloorfloorNumber : intgetFloorNumber() : intMainmain(args : String[]) : void

Also See

Comments

Popular posts from this blog

Designing a Parking Lot - Low Level Design

Problem Statement Design a parking lot that can handle vehicles entering and leaving while managing parking across multiple floors. Each vehicle should be assigned a suitable parking spot based on its type, and the spot should be freed once the vehicle exits. The design should also support generating a ticket at entry and optionally calculating the parking fee based on the duration of stay. Asked In Companies Amazon Google Microsoft Uber Walmart Flipkart Meta PayPal Oracle Salesforce Adobe Apple Intuit LinkedIn Atlassian Functional Requirements The design should support multiple vehicle types such as bikes, cars, and trucks A vehicle must be assigned a parking spot compatible with its type A parking spot cannot be assigned to more than one vehicle at a time The parking lot should support multiple levels (floors) The design should search and allocate an availa...

Most Frequently Asked Low Level Design(LLD) Interview Questions

Below are the curated list of most commonly asked Low Level Design (LLD) interview problems. Each problem includes a short description and a link to the complete solution with code and class diagrams. Design Parking Lot System The system should handle parking for different vehicle types such as bikes, cars, and trucks. It should manage slot allocation, availability tracking, and entry/exit flow. The design also ensures efficient usage of parking space under varying load conditions. View Solution Design Elevator / Lift System The system should support multiple elevators operating across floors with request handling logic. It focuses on scheduling algorithms to minimize wait time and optimize movement. It also manages direction control and concurrent floor requests. View Solution Design Movie Ticket Booking System The system should allow users to browse movies, select shows, and book seats. It handles seat ...

Software Design Patterns for LLD Interviews: A Complete Guide

Software Design Patterns for LLD Interviews: A Complete Guide In Software Development Engineer (SDE) interviews—especially for mid-level and senior roles—low-level design (LLD) rounds assess your ability to write clean, reusable, maintainable, and extensible code. The foundation of resolving these architectural challenges lies in the standard Gang of Four (GoF) Design Patterns. Rather than memorizing theoretical definitions, interviewers expect you to apply these patterns to real-world scenarios, identifying the trade-offs of each. Below is a comprehensive guide to the 12 most frequently asked design patterns in LLD interviews, categorized by their classification (Creational, Structural, and Behavioral). Each pattern contains a concrete, real-world Java implementation and a detailed breakdown of design decisions. Creational Design Patterns Creational design patterns deal with object creation mechanisms. They abstract the instantiation process, making a system independent of how...