Try Our Course for 4 Hours @99rs

Try our course for 4 Hours and if you like it, you can go for one year or lifetime access. If you buy our (1yr or lifetime) course 99rs will be refunded !

Design (LLD)  Lift - Machine Coding

Design (LLD) Lift - Machine Coding

Features Required:

  1. Lift Movement:

    • The lift should move up and down.

    • It should stop at specified floors.

  2. User Interaction:

    • Users should be able to request the lift at a particular floor.

    • Users should be able to select the floor they want to go to.

  3. Internal Logic:

    • The lift should have internal logic to decide its movement based on user requests.
  4. Emergency Handling:

    • There should be a way to handle emergency situations, such as opening the doors manually.
  5. Status Display:

    • Display the current floor and direction of the lift.

Design Patterns Involved or Used:

  1. State Pattern:

    • For representing the different states of the lift (moving up, moving down, stopped).
  2. Strategy Pattern:

    • For defining algorithms to handle user requests and determining the next floor.
  3. Observer Pattern:

    • To notify the lift when a user request is made.
  4. Command Pattern:

    • For encapsulating a request as an object, thereby allowing for parameterization of clients with different requests, queuing of requests, and logging of the actions.

Diagram

Code: Detailed Implementation

import java.util.ArrayList;
import java.util.List;

// Observer Pattern
interface Observer {
    void update(int floor);
}

// State Pattern
interface LiftState {
    void handleRequest(Lift lift, int floor);
}

class MovingUpState implements LiftState {
    public void handleRequest(Lift lift, int floor) {
        if (floor > lift.getCurrentFloor()) {
            System.out.println("Moving up to floor: " + floor);
            lift.setCurrentFloor(floor);
        }
        // Change state or stop based on requirements
    }
}

class MovingDownState implements LiftState {
    public void handleRequest(Lift lift, int floor) {
        if (floor < lift.getCurrentFloor()) {
            System.out.println("Moving down to floor: " + floor);
            lift.setCurrentFloor(floor);
        }
        // Change state or stop based on requirements
    }
}

class StoppedState implements LiftState {
    public void handleRequest(Lift lift, int floor) {
        System.out.println("Lift is stopped at floor: " + floor);
        lift.setCurrentFloor(floor);
        // Change state or stop based on requirements
    }
}

// Strategy Pattern
interface MovementStrategy {
    void move(Lift lift, int floor);
}

class DefaultMovementStrategy implements MovementStrategy {
    public void move(Lift lift, int floor) {
        lift.setState(new StoppedState());
        System.out.println("Lift is stopped at floor: " + floor);
        lift.setCurrentFloor(floor);
    }
}

class EmergencyMovementStrategy implements MovementStrategy {
    public void move(Lift lift, int floor) {
        // Emergency movement strategy
    }
}

// Command Pattern
interface LiftCommand {
    void execute();
}

class RequestCommand implements LiftCommand {
    private Lift lift;
    private int floor;

    public RequestCommand(Lift lift, int floor) {
        this.lift = lift;
        this.floor = floor;
    }

    public void execute() {
        lift.handleRequest(floor);
    }
}

// Lift class
class Lift implements Observer {
    private LiftState currentState;
    private MovementStrategy movementStrategy;
    private int currentFloor;

    public Lift() {
        this.currentState = new StoppedState();
        this.movementStrategy = new DefaultMovementStrategy();
    }

    public void handleRequest(int floor) {
        currentState.handleRequest(this, floor);
        move();
    }

    public void move() {
        movementStrategy.move(this, currentFloor);
    }

    public void update(int floor) {
        // Observer pattern update logic
    }

    public void setState(LiftState state) {
        this.currentState = state;
    }

    public void setMovementStrategy(MovementStrategy strategy) {
        this.movementStrategy = strategy;
    }

    public int getCurrentFloor() {
        return currentFloor;
    }

    public void setCurrentFloor(int currentFloor) {
        this.currentFloor = currentFloor;
    }
}

// LiftController class
class LiftController {
    private List<Lift> lifts;

    public LiftController(List<Lift> lifts) {
        this.lifts = lifts;
    }

    public void requestLift(int floor) {
        // Logic to assign a lift based on the request
        if (!lifts.isEmpty()) {
            lifts.get(0).handleRequest(floor);
        } else {
            System.out.println("No lifts available");
        }
    }
}

public class LiftApp {
    public static void main(String[] args) {
        Lift lift1 = new Lift();
        LiftController liftController = new LiftController(List.of(lift1));

        liftController.requestLift(3);
        liftController.requestLift(5);
        liftController.requestLift(2);
    }
}

Please note that this is a simplified example, and the logic might need to be adjusted based on the specific requirements and rules of your lift system.