允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。
糖果销售机有多种状态,每种状态下销售机有不同的行为,状态可以发生转移,使得销售机的行为也发生改变。
具体代码如下:
/*** 糖果销售机*/public class GumballMachine {private final State soldOutState = new SoldOutState(this);private final State noQuarterState = new NoQuarterState(this);private final State hasQuarterState = new HasQuarterState(this);private final State soldState = new SoldState(this);/*糖果销售机,当前处于的状态*/private State state;/*糖果销售机,有的糖果数量*/private int count = 0;public GumballMachine(int numberGumballs) {count = numberGumballs;if (numberGumballs > 0) {state = noQuarterState;} else {state = soldOutState;}}/*投币,投了25美分*/public void insertQuarter() {state.insertQuarter();}/*退币,退了25美分*/public void ejectQuarter() {state.ejectQuarter();}/*转动曲柄*/public void turnCrank() {state.turnCrank(); //转动曲柄state.dispense(); //弹出糖果}public void releaseBall() {if (count > 0) {count--;System.out.println("糖果销售机中,弹出一颗糖果……");}else {System.out.println("糖果销售机中,没有弹出糖果……");}}public void setState(State state) {this.state = state;}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;}}
/*** 糖果销售机,某一刻所处的状态*/public interface State {/*** 投入 25 分钱*/void insertQuarter();/*** 退回 25 分钱*/void ejectQuarter();/*** 转动糖果销售机曲柄*/void turnCrank();/*** 糖果销售机,发放糖果*/void dispense();}
/*** 为投币状态*/public class NoQuarterState implements State {private GumballMachine gumballMachine;public NoQuarterState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {System.out.println("你已经投币了");gumballMachine.setState(gumballMachine.getHasQuarterState());}@Overridepublic void ejectQuarter() {System.out.println("你不能退币,因为你没投币");}@Overridepublic void turnCrank() {System.out.println("你不能转动糖果销售机曲柄,因为你没投币");}@Overridepublic void dispense() {System.out.println("没有弹出糖果");}}
/*** 投币状态*/public class HasQuarterState implements State {private GumballMachine gumballMachine;public HasQuarterState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {System.out.println("你已投币,不能再投了");}@Overridepublic void ejectQuarter() {System.out.println("退币成功");/*退币成功,切换到:未投币状态*/gumballMachine.setState(gumballMachine.getNoQuarterState());}@Overridepublic void turnCrank() {System.out.println("你转动糖果销售机曲柄");/*你转动曲柄,状态切换为:糖果销售机弹出糖果状态*/gumballMachine.setState(gumballMachine.getSoldState());}@Overridepublic void dispense() {System.out.println("没有弹出糖果");}}
/*** 糖果销售机,弹出糖果状态*/public class SoldState implements State {private GumballMachine gumballMachine;public SoldState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {System.out.println("你已投币,不能再投了");}@Overridepublic void ejectQuarter() {System.out.println("你不能退币,因为你已经使用了");}@Overridepublic void turnCrank() {System.out.println("转动糖果销售机曲柄,你能弹出一个糖果");}@Overridepublic void dispense() {/*糖果数量 减一*/gumballMachine.releaseBall();if (gumballMachine.getCount() > 0) {/*糖果销售机中有糖果,状态切换为:为投币状态*/gumballMachine.setState(gumballMachine.getNoQuarterState());} else {/*糖果销售机中没有糖果,状态切换为:糖果售完状态*/System.out.println("哎呀!糖果销售机的糖果售完了");gumballMachine.setState(gumballMachine.getSoldOutState());}}}
/*** 糖果买完状态*/public class SoldOutState implements State {private GumballMachine gumballMachine;public SoldOutState(GumballMachine gumballMachine) {this.gumballMachine = gumballMachine;}@Overridepublic void insertQuarter() {System.out.println("你不能投币了,因为糖果已售完");}@Overridepublic void ejectQuarter() {System.out.println("你不能退币,因为你没投币");}@Overridepublic void turnCrank() {System.out.println("你能转动糖果销售机曲柄,但是糖果已售完");}@Overridepublic void dispense() {System.out.println("没有糖果弹出,因为糖果已售完");}}
package com.example.greamrodcode.pattern2;public class Client {public static void main(String[] args) {GumballMachine gumballMachine = new GumballMachine(5);gumballMachine.insertQuarter();gumballMachine.turnCrank();System.out.println("=============================================");gumballMachine.insertQuarter();gumballMachine.ejectQuarter();gumballMachine.turnCrank();System.out.println("=============================================");gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.ejectQuarter();System.out.println("=============================================");gumballMachine.insertQuarter();gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();gumballMachine.insertQuarter();gumballMachine.turnCrank();}}
你已经投币了你转动糖果销售机曲柄糖果销售机中,弹出一颗糖果……=============================================你已经投币了退币成功你不能转动糖果销售机曲柄,因为你没投币没有弹出糖果=============================================你已经投币了你转动糖果销售机曲柄糖果销售机中,弹出一颗糖果……你已经投币了你转动糖果销售机曲柄糖果销售机中,弹出一颗糖果……你不能退币,因为你没投币=============================================你已经投币了你已投币,不能再投了你转动糖果销售机曲柄糖果销售机中,弹出一颗糖果……你已经投币了你转动糖果销售机曲柄糖果销售机中,弹出一颗糖果……哎呀!糖果销售机的糖果售完了你不能投币了,因为糖果已售完你能转动糖果销售机曲柄,但是糖果已售完没有糖果弹出,因为糖果已售完
