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; // system calls public int getChange(int returnChangeMoney) throws Exception; public Item dispenseProduct(VendingMachine machine, int codeNumber) throws Exception; public List<Coin> refundFullMoney(VendingMachine machine) throws Exception; // for internal use only public void updateInventory(VendingMachine machine, Item item, int codeNumber) throws Exception;}
Implement States:
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); }}public class HasMoneyState implements State { // implementation}public class SelectionState implements State { // implementation}public class DispenseState implements State { // implementation}public class DispenseState implements State { // implementation}
Inventory > ItemShelf > Item
public class Inventory { ItemShelf[] inventory = null; // possibly use array because list of shelves is not going to be changed Inventory(int itemCount) { inventory = new ItemShelf[itemCount]; initialEmptyInventory(); } // other implementation}public class ItemShelf { int code; Item item; boolean soldOut;}public class Item { ItemType type; int price;}public enum ItemType { COKE, PEPSI, JUICE, SODA;}
Coin (generally vending machines have coin system)
public enum Coin { PENNY(1), NICKEL(5), DIME(10), QUARTER(25); public int value; Coin(int value) { this.value = value; }}
Vending Machine
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<>(); } // other implementation}
Driver
Maybe we can have a while loop, for each operation, it will get the state and perform operation
public class Main { public static void main(String args[]){ VendingMachine vendingMachine = new VendingMachine(); try { State vendingState = vendingMachine.getVendingMachineState(); vendingState.clickOnInsertCoinButton(vendingMachine); vendingState = vendingMachine.getVendingMachineState(); vendingState.insertCoin(vendingMachine, Coin.NICKEL); vendingState.insertCoin(vendingMachine, Coin.QUARTER); vendingState = vendingMachine.getVendingMachineState(); vendingState.clickOnStartProductSelectionButton(vendingMachine); vendingState = vendingMachine.getVendingMachineState(); vendingState.chooseProduct(vendingMachine, 102); displayInventory(vendingMachine); } catch (Exception e){ displayInventory(vendingMachine); } }}