OOP: Elevator Design - mbhushan/codique GitHub Wiki

Design an elevator control system

Interfaces:
-----------------
IElevator:
+ moveUp();
+ moveDown();
+ addDestination();

+ ElevatorStatus status();
+ ElevatorDirection direction();
---------------------

IElevatorControl:
+ pickUp(Integer pickUpFloor);
+ destination(Integer elevatorId, Integer destinationFloor);
+ step();
Enums:
ElevatorStatus:
+ ELEVATOR_BUSY,
+ ELEVATOR_FREE;
-----------------------

ElevatorDirection:
+ ELEVATOR_UP,
+ ELEVATOR_DOWN,
+ ELEVATOR_HOLD;
Classes:
Elevator implements IElevator:
- currentFloor: Integer
- targetFloor: PriorityQueue<Integer> //smallest to largest if UP, else reverse.

public Elevator(int currentFloor) {
		this.currentFloor = currentFloor;
		this.targetFloor = new PriorityQueue<Integer>(10);
}

public int nextDestination() {
		return this.targetFloor.peek();
}

public int currentFloor() {
		return this.currentFloor;
}

public void popDestination() {
		this.targetFloor.poll();
}

       @Override
	public void moveUp() {
		++this.currentFloor;
	}

	@Override
	public void moveDown() {
		--this.currentFloor;
	}

	@Override
	public void addDestination(Integer destination) {
		this.targetFloor.add(destination);
	}

        @Override
	public ElevatorDirection direction() {
		if (this.targetFloor.size() > 0) {
			if (this.currentFloor < this.targetFloor.peek()) {
				return ElevatorDirection.ELEVATOR_UP;
			} else if (this.currentFloor > this.targetFloor.peek()) {
				return ElevatorDirection.ELEVATOR_DOWN;
			}
		}
		return ElevatorDirection.ELEVATOR_HOLD;
	}

	@Override
	public ElevatorStatus status() {
		return this.targetFloor.size() > 0 ? ElevatorStatus.ELEVATOR_BUSY: ElevatorStatus.ELEVATOR_FREE;
	}

ElevatorControl implements IElevatorControl:
        public static final int MAX_ELEVATORS = 4;
	private int numElevators = 0;
	private int numFloors = 0;
	List<Elevator> elevators;
	PriorityQueue<Integer> pickupFloors;

	public ElevatorControlSystem(int numElevators, int numFloors) throws InvalidNumberInput {
		if (numElevators < 1) {
			throw new InvalidNumberInput("number of elevators has to be positive!");
		}
		if (numFloors < 1) {
			throw new InvalidNumberInput("number of floors has to be positive!");
		}

		this.numElevators = (numElevators > MAX_ELEVATORS) ? MAX_ELEVATORS: numElevators;
		this.numFloors = numFloors;
		
		initElevators();
		pickupFloors = new PriorityQueue<Integer>(10);
	}

        private void initElevators() {
		this.elevators = new ArrayList<Elevator>();
		for (int id=0; id<this.numElevators; id++) {
			this.elevators.add(new Elevator(id));
		}
	}

        @Override
	public void pickUp(Integer pickUpFloor) {
		this.pickupFloors.add(pickUpFloor);
	}

	@Override
	public void destination(Integer elevatorId, Integer destinationFloor) {
		this.elevators.get(elevatorId).addDestination(destinationFloor);
	}


	@Override
	public void step() {
		for (Elevator elv: this.elevators) {
			switch(elv.status()) {
			case ELEVATOR_FREE:
				if (!pickupFloors.isEmpty()) {
					elv.addDestination(pickupFloors.poll());
				}
				break;
			case ELEVATOR_BUSY:
				switch (elv.direction()){
	            case ELEVATOR_UP:
	              elv.moveUp();
	              break;
	            case ELEVATOR_DOWN:
	              elv.moveDown();
	              break;
	            case ELEVATOR_HOLD:
	              // TODO: can be more sophisticated, emergency, alert, maintenance. 
	              elv.popDestination();
	              break;
	          }
			}
		}
	}

⚠️ **GitHub.com Fallback** ⚠️