设计模式-状态模式
状态模式:

允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。要点:
- 状态模式允许一个对象基于内部状态而拥有不同的行为。
- 和程序状态机不同,状态模式用类代表状态。
- Context会将行为委托给当前状态对象。
- 通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。
- 状态模式和策略模式有相同的类图,但是它们的意图不同。
- 策略模式通常会用行为或算法来配置Context类。
- 状态模式允许Context随着状态的改变而改变行为。
- 状态转换可以有State类或Context类控制。
- 使用状态模式通常会导致设计中类的数目大量增加。
- 状态类可以被多个Context实例共享。
public interface State { /** * 投币业务 */ void insertQuarter(); /** * 退币业务 */ void ejectQuarter(); /** * 转动曲柄业务 */ void turnCrank(); /** * 发放糖果代码 */ void dispense(); }
/** * 有钱状态 */ public class HasQuarterState implements State{ GumballMachine gumballMachine; Random randomWinner = new Random(System.currentTimeMillis()); public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println("........你已投过钱了!"); } public void ejectQuarter() { System.out.println("........退出客户投入的钱"); gumballMachine.setState(gumballMachine.getNoQuarterState()); } public void turnCrank() { System.out.println("........客户转动曲柄"); int winner = randomWinner.nextInt(10); if ((winner == 0)&&(gumballMachine.getCount()>1)){ System.out.println("》》》》》》》》获得两次发放机会"); gumballMachine.setState(gumballMachine.getWinnerState()); } else { gumballMachine.setState(gumballMachine.getSoldState()); } } public void dispense() { System.out.println("........不能发放糖果"); } }
/** * 糖果售罄 */ public class SoldOutState implements State{ GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println(".....糖果售罄了,不要投币了"); } public void ejectQuarter() { System.out.println(".....售罄糖果不支持退币业务"); } public void turnCrank() { System.out.println(".....售罄糖果不支持转动曲柄"); } public void dispense() { System.out.println(".....售罄了,不支持发放糖果业务"); } }
/** * 发放糖果活动 */ public class WinnerState implements State{ GumballMachine gumballMachine; public WinnerState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println(".....正在出糖果,稍后再投"); } public void ejectQuarter() { System.out.println(".....正在出售糖果,无法退款"); } public void turnCrank() { System.out.println(".....正在售出糖果,稍后操作"); } public void dispense() { System.out.println(".....你有两出两颗糖果的机会"); gumballMachine.releaseBall(); if (gumballMachine.getCount()==0){ gumballMachine.setState(gumballMachine.getSoldOutState()); } else { gumballMachine.releaseBall(); if (gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoQuarterState()); }else { System.out.println("糖果售罄"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } } }
/** * 没投钱 */ public class NoQuarterState implements State{ GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println(".....投钱,改状态"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } public void ejectQuarter() { System.out.println(".....没给钱,不能退钱"); } public void turnCrank() { System.out.println(".....没给钱,不能转动曲柄"); } public void dispense() { System.out.println(".....没有钱,不发糖果"); } }
/** * 售出糖果 */ public class SoldState implements State{ GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } public void insertQuarter() { System.out.println(".....正在售出糖果,请稍后操作"); } public void ejectQuarter() { System.out.println(".....售出糖果不能退款"); } public void turnCrank() { System.out.println(".....售出糖果不能转动曲柄"); } public void dispense() { System.out.println(".....正在售出!"); gumballMachine.releaseBall(); if (gumballMachine.getCount()>0){ gumballMachine.setState(gumballMachine.getNoQuarterState()); } else { System.out.println("糖果卖完了"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } }
public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State winnerState; State state = soldOutState; int count =0; public GumballMachine(int numberGumballs) { this.soldOutState = new SoldOutState(this); this.noQuarterState = new NoQuarterState(this); this.hasQuarterState = new HasQuarterState(this); this.soldState = new SoldState(this); this.count = numberGumballs; if(numberGumballs>0){ state = noQuarterState; } } public void insertQuarter(){ state.insertQuarter(); } public void ejectQuarter(){ state.ejectQuarter(); } public void turnCrank(){ state.turnCrank(); state.dispense(); } void releaseBall(){ System.out.println(".。。。。。。。释放糖果,数量-1"); if (count !=0){ count = count-1; } } public State getSoldOutState() { return soldOutState; } public void setSoldOutState(State soldOutState) { this.soldOutState = soldOutState; } public State getNoQuarterState() { return noQuarterState; } public void setNoQuarterState(State noQuarterState) { this.noQuarterState = noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public void setHasQuarterState(State hasQuarterState) { this.hasQuarterState = hasQuarterState; } public State getSoldState() { return soldState; } public void setSoldState(State soldState) { this.soldState = soldState; } public State getState() { return state; } public void setState(State state) { this.state = state; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public State getWinnerState() { return winnerState; } public void setWinnerState(State winnerState) { this.winnerState = winnerState; } @Override public String toString() { return "GumballMachine{" + "soldOutState=" + soldOutState + ", noQuarterState=" + noQuarterState + ", hasQuarterState=" + hasQuarterState + ", soldState=" + soldState + ", winnerState=" + winnerState + ", state=" + state + ", count=" + count + '}'; } }
public class Test { public static void main(String[] args) { GumballMachine gumballMachine = new GumballMachine(5); System.out.println(".........1:"+gumballMachine.getCount()); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(".........2:"+gumballMachine.getCount()); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println(".........3:"+gumballMachine.getCount()); } }