Elevator

This I have written as part of my LLD Practice. Please let me know further imporvements that can be done.

Also tell current design is Strong/Average/Lean Hire ?

Other Design Problems

/*

Design Patterns Used:
- Strategy
- Observer

*/
/*
Elevator

- User can press button in elevator to reach required destination
- User can call elevator in the direction they want to go
- Elevator should be called based on some strategy
- Upon reaching destination doors should open automatically

*/

import java.util.Arrays;
import java.util.List;
import java.util.Queue;

enum Direction{
    UP, DOWN, IDLE
}

enum ElevatorState{
    Idle, Moving, Stopped, Maintainance
}

enum DoorState{
    Open, Closed
}

abstract class Request{
    int floor;

    Request(int floor){
        this.floor=floor;
    }
}

class InternalRequest extends Request{
    InternalRequest(int floor){
        super(floor);
    }
}

class ExternalRequest extends Request{
    Direction direction;
    ExternalRequest(Direction direction, int floor){
        super(floor);
        this.direction=direction;
    }
}

interface ElevatorObserver{
    void onElevatorStateChange(Elevator elevator, ElevatorState elevatorState);
    void onElevatorFloorChange(Elevator elevator, int floor);
}

class ElevatorDisplay implements ElevatorObserver{
    @Override
    public void onElevatorStateChange(Elevator elevator, ElevatorState elevatorState){

    }

    @Override
    public void onElevatorFloorChange(Elevator elevator, int floor){

    }
}

interface ElevatorAssignStrategy{
    Elevator assignElevator(List<Elevator> elevators, ExternalRequest request);
}

class RoundRobinStrategy implements ElevatorAssignStrategy{
    @Override
    public Elevator assignElevator(List<Elevator> elevators, ExternalRequest request){

    }
}

class Elevator{
    String id;
    int currFloor;
    Direction direction;
    DoorState doorState;
    ElevatorState elevatorState;
    List<ElevatorObserver> observers;
    Queue<Request> requests;

    void addObserver(ElevatorObserver elevatorObserver){
        observers.add(elevatorObserver);
    }

    void notifyStateChange(){
        for(ElevatorObserver obs:observers){
            obs.onElevatorStateChange(this,elevatorState);
        }
    }

    void notifyFloorChange(){
        for(ElevatorObserver obs:observers){
            obs.onElevatorFloorChange(this,currFloor);
        }
    }

    void addRequest(Request request){
        requests.offer(request);
        processRequests();
    }

    void processRequests(){
        while(!requests.isEmpty()){
            Request request= requests.poll();
            moveToFloor(request.floor);
        }
    }

    void moveToFloor(int dstFloor){
        elevatorState=ElevatorState.Moving;
        notifyStateChange();

        while(currFloor!=dstFloor){
            if(currFloor<dstFloor){
                currFloor++;
                direction=Direction.UP;
            }
            else{
                currFloor--;
                direction=Direction.DOWN;
            }
            notifyFloorChange();
        }

        direction=Direction.IDLE;
        elevatorState=ElevatorState.Stopped;
        notifyStateChange();

        openDoor();
        closeDoor();

        elevatorState=ElevatorState.Idle;
        notifyStateChange();
    }

    void openDoor(){
        doorState=DoorState.Open;
    }

    void closeDoor(){
        doorState=DoorState.Closed;
    }
}

class ElevatorController{
    List<Elevator> elevators;
    ElevatorAssignStrategy strategy;

    void handleExternalRequest(ExternalRequest request){
        Elevator elevator=strategy.assignElevator(elevators,request);
        if(elevator!=null) elevator.addRequest(request);
    }

    void handleInternalRequest(Elevator elevator, InternalRequest request){
        elevator.addRequest(request);
    }
}


public class Elevator {
    public static void main(String[] args) {
        Elevator e1=new Elevator();
        Elevator e2=new Elevator();
        Elevator e3=new Elevator();

        ElevatorObserver display=new ElevatorDisplay();
        e1.addObserver(display);
        e2.addObserver(display);
        e3.addObserver(display);

        List<Elevator> elevators= Arrays.asList(e1,e2,e3);

        ElevatorController controller=new ElevatorController();

        controller.handleExternalRequest(new ExternalRequest(Direction.DOWN,3));
        controller.handleInternalRequest(new Elevator(),new InternalRequest(4));
    }
}
Comments (0)