利用状态模式前我们的代码:
public class GumballMachine { final static int SOLD_OUT = 0; final static int NO_QUARTER = 1; final static int HAS_QUARTER = 2; final static int SOLD = 3; int state = SOLD_OUT; int count = 0; public GumballMachine(int count) { this.count = count; if (count > 0) { state = NO_QUARTER; } } // 投入钱 public void insertQuarter() { if (state == HAS_QUARTER) { System.out.println("You can't insert another quarter"); } else if (state == NO_QUARTER) { state = HAS_QUARTER; System.out.println("You inserted a quarter"); } else if (state == SOLD_OUT) { System.out.println("the machine is sold out"); } else if (state == SOLD) { System.out.println("please wait,Are Shopping"); } } // 退钱 public void ejectQuarter() { if (state == HAS_QUARTER) { System.out.println("quarter returned"); state = NO_QUARTER; } else if (state == NO_QUARTER) { System.out.println("You haven't inserted a quarter"); } else if (state == SOLD) { System.out.println("sorry,you already get a goods"); } else if (state == SOLD_OUT) { System.out .println("you can't eject,you haven't insert a quarter yet"); } } // 转动扭杆 public void turnCrank() { if (state == SOLD) { System.out.println("you already get a goods"); } else if (state == NO_QUARTER) { System.out.println("you don't insert Quarter"); } else if (state == SOLD_OUT) { System.out.println("no goods now"); } else if (state == HAS_QUARTER) { System.out.println("are shopping"); state = SOLD; despense(); } } private void despense() { if (state == SOLD) { System.out.println("A gumball comes rolling out the slot"); count--; if (count == 0) { state = SOLD_OUT; } else { state = NO_QUARTER; } } else if (state == NO_QUARTER) { System.out.println("you don't insert Quarter"); } else if (state == SOLD_OUT) { System.out.println("no goods dispensed"); } else if (state == HAS_QUARTER) { System.out.println("no goods dispensed"); } } @Override public String toString() { return "GumballMachine [state=" + state + ", count=" + count + "]"; } }
测试程序
public class GumballMachineTestDrive { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(5); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.ejectQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.ejectQuarter(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); } }
输出
GumballMachine [state=1, count=5] You inserted a quarter are shopping A gumball comes rolling out the slot GumballMachine [state=1, count=4] You inserted a quarter quarter returned you don't insert Quarter GumballMachine [state=1, count=4] You inserted a quarter are shopping A gumball comes rolling out the slot You inserted a quarter are shopping A gumball comes rolling out the slot You haven't inserted a quarter GumballMachine [state=1, count=2] You inserted a quarter You can't insert another quarter are shopping A gumball comes rolling out the slot You inserted a quarter are shopping A gumball comes rolling out the slot the machine is sold out no goods now GumballMachine [state=0, count=0]
利用状态模式后代码变为如下形式
状态接口state
public interface State { void insertQuarter(); void ejectQuarter(); void turnCrank(); void dispense(); }
public class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("You inserted a quarter!"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } @Override public void ejectQuarter() { System.out.println("You haven't inserted a quarter"); } @Override public void turnCrank() { System.out.println("You turned ,but there's no quarter"); } @Override public void dispense() { System.out.println("You need to pay first"); } }
public class HasQuarterState implements State { GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("Has Quarter,can't insert again!"); } @Override public void ejectQuarter() { System.out.println("quarter returned"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } @Override public void turnCrank() { System.out.println("You turned..."); gumballMachine.setState(gumballMachine.getSoldState()); } @Override public void dispense() { System.out.println("No gumball dispensed!"); } }
public class SoldOutState implements State { GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("sorry,gumball has sold out!"); } @Override public void ejectQuarter() { // TODO Auto-generated method stub System.out .println("sorry,you don't insert quarter,but gumball has sold out!"); } @Override public void turnCrank() { // TODO Auto-generated method stub System.out .println("sorry,you don't insert quarter,but gumball has sold out!"); } @Override public void dispense() { System.out.println("sorry,gumball has sold out!"); } }
public class SoldState implements State { GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { System.out.println("please wait,we're already giving you a gumball"); } @Override public void ejectQuarter() { System.out.println("sorry,you alread turned the crank!"); } @Override public void turnCrank() { System.out.println("turning twice doesn't get you another gumball"); } @Override public void dispense() { gumballMachine.releaseBall(); if (gumballMachine.getCount() > 0) { gumballMachine.setState(gumballMachine.getNoQuarterState()); } else { gumballMachine.setState(gumballMachine.getSoldOutState()); } } }
public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State state = soldOutState; int count = 0; public GumballMachine(int count) { soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldState = new SoldState(this); this.count = count; if (count > 0) { state = noQuarterState; } } public void insertQuarter() { state.insertQuarter(); } public void ejectQuarter() { // TODO Auto-generated method stub state.ejectQuarter(); } public void turnCrank() { // TODO Auto-generated method stub state.turnCrank(); state.dispense(); } void setState(State state) { this.state = state; } void releaseBall() { System.out.println("A gumball comes rolling out the slot ..."); if (count != 0) { --count; } } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } public int getCount() { return count; } @Override public String toString() { return "GumballMachine [count=" + count + "]"; } }
public class GumballMachineTestDrive { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(5); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.ejectQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.ejectQuarter(); System.out.println(gumballMachine); gumballMachine.insertQuarter(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(gumballMachine); } }
GumballMachine [count=5] You inserted a quarter! You turned... A gumball comes rolling out the slot ... GumballMachine [count=4] You inserted a quarter! quarter returned You turned ,but there's no quarter You need to pay first GumballMachine [count=4] You inserted a quarter! You turned... A gumball comes rolling out the slot ... You inserted a quarter! You turned... A gumball comes rolling out the slot ... You haven't inserted a quarter GumballMachine [count=2] You inserted a quarter! Has Quarter,can't insert again! You turned... A gumball comes rolling out the slot ... You inserted a quarter! You turned... A gumball comes rolling out the slot ... sorry,gumball has sold out! sorry,you don't insert quarter,but gumball has sold out! sorry,gumball has sold out! GumballMachine [count=0]
State Pattern
允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。