I'm trying to implement vending machine using state design pattern. The problem is that the state interface contain some methods which might not be relevant to some concrete implementations of the state interface. As a result it violates the interface segregation principle. So how can we implement it without violating it? How will the project structure and implementation of state context will look like?
My state interface :
public interface State {
public void clickOnInsertCoinButton(VendingMachine machine) throws Exception;
public void clickOnStartProductSelectionButton(VendingMachine machine) throws Exception;
public void insertCoin(VendingMachine machine , Coin coin) throws Exception;
public void chooseProduct(VendingMachine machine, int codeNumber) throws Exception;
public int getChange(int returnChangeMoney) throws Exception;
public Item dispenseProduct(VendingMachine machine, int codeNumber) throws Exception;
public List<Coin> refundFullMoney(VendingMachine machine) throws Exception;
public void updateInventory(VendingMachine machine, Item item, int codeNumber) throws Exception; }
Concrete state implementations:
public class IdleState implements State {
public IdleState(){
System.out.println("Currently Vending machine is in IdleState");
}
public IdleState(VendingMachine machine){
System.out.println("Currently Vending machine is in IdleState");
machine.setCoinList(new ArrayList<>());
}
@Override
public void clickOnInsertCoinButton(VendingMachine machine) throws Exception{
machine.setVendingMachineState(new HasMoneyState());
}
@Override
public void clickOnStartProductSelectionButton(VendingMachine machine) throws Exception {
throw new Exception("first you need to click on insert coin button");
}
@Override
public void insertCoin(VendingMachine machine, Coin coin) throws Exception{
throw new Exception("you can not insert Coin in idle state");
}
@Override
public void chooseProduct(VendingMachine machine, int codeNumber) throws Exception{
throw new Exception("you can not choose Product in idle state");
}
@Override
public int getChange(int returnChangeMoney) throws Exception{
throw new Exception("you can not get change in idle state");
}
@Override
public List<Coin> refundFullMoney(VendingMachine machine) throws Exception{
throw new Exception("you can not get refunded in idle state");
}
@Override
public Item dispenseProduct(VendingMachine machine, int codeNumber) throws Exception{
throw new Exception("proeduct can not be dispensed idle state");
}
@Override
public void updateInventory(VendingMachine machine, Item item, int codeNumber) throws Exception {
machine.getInventory().addItem(item, codeNumber);
}
}
3 more concrete state implementations are there with some not all methods overridden.
State Context:
public class VendingMachine {
private State vendingMachineState;
private Inventory inventory;
private List<Coin> coinList;
public VendingMachine(){
vendingMachineState = new IdleState();
inventory = new Inventory(10);
coinList = new ArrayList<>();
}
public State getVendingMachineState() {
return vendingMachineState;
}
public void setVendingMachineState(State vendingMachineState) {
this.vendingMachineState = vendingMachineState;
}
public Inventory getInventory() {
return inventory;
}
public void setInventory(Inventory inventory) {
this.inventory = inventory;
}
public List<Coin> getCoinList() {
return coinList;
}
public void setCoinList(List<Coin> coinList) {
this.coinList = coinList;
}
}