I am trying to implement a VendingMachine
which has multiple states (Idle, ProductSelected, ReceivedMoney, ProductDispatched
). Each state implements method in VendingMachineState
(for simplicity consider just collectMoney(int amount)
). Methods like collectMoney()
do their job and then change the state to the next state as per the state machine.
Interface VendingMachineState
and all their implementing classes are used by class VendingMachine
via composition. VendingMachine
maintains a current state in currentState
, and exposes a method setCurrentState()
to update its current state. The same method is used by ProductSelected, ReceivedMoney, ..
to change the state of VendingMachine
.
public interface VendingMachineState {
void selectProduct(String name);
void collectMoney(int money);
void dispatch(int product);
}
class Idle implements VendingMachineState {
private final VendingMachine v;
public Idle(VendingMachine v) {
this.v = v;
}
public void selectProduct(String name) {
v.setCurrentProduct(name);
v.setCurrentState(v.productSelected);
}
}
class ProductSelected implements VendingMachineState {
...
}
public class VendingMachine {
private final VendingMachineState idle, productSelected, moneyReceived, dispatched;
private VendingMachineState currentState;
public VendingMachine() {
idle = new Idle(this);
productSelected = new ProductSelected();
...
currentState = idle;
}
void setCurrentState(VendingMachineState newState) {
currentState = newState;
}
Is the above design good and acceptable? Isn’t that a cyclic dependency (VendingMachine
having dependencies on VendingMachineState, Idle, ProductSelected, ..
as well as VendingMachineState, Idle, ..
having dependency on VendingMachine).
If yes, what is the standard way of implementing such state machine to avoid cyclic dependency? Or it doesn’t even qualify as a cyclic dependency and this implementation seem okay?
Thanks you so much!
hrishi is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.