Ho bisogno di rafforzare le mie abilità OOP
e quindi ho pensato di implementare un simulatore di Elevator. Inizialmente quello che sembra essere un design semplice è diventato un disastro completo e mi ha lasciato confuso sulla mia conoscenza di OOP
. Di seguito sono riportate le classi di implementazione.
/**
* 1. User enter the elevator.
* 2. Elevator checks the maximum capacity.
* 3. User enters the floor number.
* 4. Elevator registers the request.
* 5. Elevator checks the next request and stops at that floor.
* 6. When elevator is in the halt state the door opens.
*/
enum State {
UP,
DOWN,
HALT
}
enum Command {
ALARM,
OPEN,
CLOSE,
GROUND,
FIRST,
SECOND
}
enum Floor {
GROUND,
FIRST,
SECOND
}
interface Engine {
public void moveTO(Floor floor);
}
interface Alarm {
public void ring();
}
interface Sensor {
public int getWeight();
public int shouldCloseDoor();
}
final class Panel {
private final Command[] commands;
private final Elevator elevator;
Panel(Command[] commands, Elevator elevator) {
this.commands = commands;
this.elevator = elevator;
}
public void onKeyPress(Command command) {
if (command == Command.OPEN) {
elevator.stop();
} else if (command == Command.CLOSE) {
elevator.move();
} else if (command == Command.GROUND) {
elevator.gotoFloor(Floor.GROUND);
} else if (command == Command.FIRST) {
elevator.gotoFloor(Floor.FIRST);
} else if (command == Command.SECOND) {
elevator.gotoFloor(Floor.SECOND);
}
}
}
final class Door {
private boolean final open;
Door() {
open = false;
}
public void open() {
if (open) return;
try {
Thread.sleep(1000); //1000 milliseconds is one second.
open = true;
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
close();
}
}
public void close() {
open = false;
}
}
// Handle elevator logic. Here the assumption is that the elevator has to come
// back to ground floor if there are not any pending requests. There are two
// queues which handles the floor requests, the elevator keeps moving in the
// direction of the queue until that queue is not empty. If the elevator reaches
// the top floor and there is no pending request then the elevator comes down to
// ground floor and comes to the halting state.
class Elevator {
public static final int MAX_WEIGHT_ALLOWED = 1600;
private final State state;
private final Door door;
private final Floor floor;
private final Queue<Floor> queueUp;
private final Queue<Floor> queueDOwn;
private final Engine engine;
private final Sensor sensor;
private final Alaram alarm;
Elevator(Door door, Engine engine, Sensor sensor, Alaram alarm) {
this.door = door;
this.queueUp = new Queue<Floor>();
this.queueDown = new Queue<Floor>();
this.state = State.HALT
this.floor = Floor.ZERO;
this.engine = engine;
this.sensor = sensor;
this.alarm = alarm;
}
public void stop() {
door.open();
state = State.HALT;
engine.stop();
System.out.println("Elevator is in stopped state.");
}
private void moveUp() {
while(!queueUp.isEmpty()) {
floor = queueUp.dequeue();
engine.moveTO(floor);
}
// All up requests are served.
state = state.DOWN;
gotoFloor(Floor.ZERO);
}
private void moveDown() {
while(!queueDown.isEmpty()) {
floor = queueUp.dequeue();
engine.moveTO(floor);
}
// All down requests served.
state = State.UP;
}
public void move() {
if (sensor.getWeight() > Elevator.MAX_WEIGHT_ALLOWED) {
alarm.ring();
stop();
return;
}
if (!sensor.shouldCloseDoor()) {
alarm.ring();
stop();
return;
}
door.close();
if (state == State.UP) {
moveUp();
} else if (state == State.DOWN) {
moveDOwn();
}
// Both the queues are empty
state = State.HALT;
System.out.println("Elevator is moving to floor: " + );
}
public void gotoFloor(Floor nextFloor) {
if (floor < nextFloor)
queueDown.enqueue(floor);
else
queueUp.enqueue(floor);
move();
}
}
public class ElevatorSimulator {
public static void main(String[] args) {
Elevator elevator = new Elevator(
new Door(), new Engine(), new Sensor(), new Alarm());
Panel panel = new Panel(Command.values(), elevator);
panel.onKeyPress(Command.OPEN);
panel.onKeyPress(Command.CLOSE);
panel.onKeyPress(Command.FIRST);
}
}
Ho sentito che pensare e annotare il requisito aiuta molto e ho provato anche io, ma penso di aver fallito completamente anche in questo scenario.
Domanda
- Buona strategia per risolvere un insieme di requisiti.
- Evita il sovraccarico cognitivo e concentrati sulla progettazione di alto livello piuttosto che passare a dettagli di distrazione.
- Elenca e gestisci le dipendenze.
- In generale, come affrontare un buon progetto:)