状态模式容许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。ide
要点:this
/** * 状态接口 */ public interface State { /** * 根据状态进行处理的方法 */ public void handle(); }
/** * 持有状态的上下文类 */ public class Context { private State state; public State getState() { return state; } public void setState(State state) { this.state = state; } /** * 接收请求,并将请求委托给状态类 */ public void request() { state.handle(); } }
/** * 具体状态A */ public class ConcreteStateA implements State { Context context; public ConcreteStateA() { context = new Context(); } @Override public void handle() { // 实现该状态下相应的行为 System.out.println("Context is in A state, and start to do something..."); context.setState(this); } }
/** * 具体状态B */ public class ConcreteStateB implements State { Context context; public ConcreteStateB() { context = new Context(); } @Override public void handle() { // 实现该状态下相应的行为 System.out.println("Context is in B state, and start to do something..."); context.setState(this); } }
public class Test { public static void main(String[] args) { // 上下文 Context context = new Context(); // 状态 State stateA = new ConcreteStateA(); State stateB = new ConcreteStateB(); // 经过状态改变行为 context.setState(stateA); context.request(); context.setState(stateB); context.request(); } }
万能糖果公司打算使用 Java 来实现糖果机的控制器。他们但愿设计可以尽可能有弹性并且好维护,由于未来可能要为糖果机增长更多的行为。设计
糖果机的工做流程以下:code
/** * 状态接口 */ public interface State { /** * 投入25分钱 */ public void insertQuarter(); /** * 退回25分钱 */ public void ejectQuarter(); /** * 转动曲柄 */ public void turnCrank(); /** * 发放糖果 */ public void dispense(); }
将传递给糖果机的请求,委托给状态类。对象
/** * 糖果机 */ public class GumballMachine { State soldOutState; State noQuarterState; State hasQuarterState; State soldState; State state = soldOutState; int gumballCount = 0; public GumballMachine(int initGumballCount) { soldOutState = new SoldOutState(this); noQuarterState = new NoQuarterState(this); hasQuarterState = new HasQuarterState(this); soldState = new SoldState(this); // 初始化糖果数量 this.gumballCount = initGumballCount; // 初始化糖果机状态 if (initGumballCount > 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() { System.out.println("A gumball comes rolling out the slot..."); if (gumballCount > 0) { gumballCount = gumballCount -1; } } public void setState(State state) { this.state = state; } public int getGumballCount() { return gumballCount; } public State getSoldOutState() { return soldOutState; } public State getNoQuarterState() { return noQuarterState; } public State getHasQuarterState() { return hasQuarterState; } public State getSoldState() { return soldState; } }
/** * 未投入25分钱状态 */ public class NoQuarterState implements State { GumballMachine gumballMachine; public NoQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { // 投入25分钱,并转到已投入25分钱状态 System.out.println("You inserted a quarter"); gumballMachine.setState(gumballMachine.getHasQuarterState()); } @Override public void ejectQuarter() { // 当前为未投入25分钱状态,不能退回25分钱 System.out.println("You haven't inserted a quarter"); } @Override public void turnCrank() { // 当前为未投入25分钱状态,不能转动曲柄 System.out.println("You truned, but there's no quarter"); } @Override public void dispense() { // 当前为未投入25分钱状态,不能发放糖果 System.out.println("You need to pay first"); } }
/** * 已投入25分钱状态 */ public class HasQuarterState implements State { GumballMachine gumballMachine; public HasQuarterState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { // 当前为已投入25分钱状态,不能再次投入 System.out.println("You can't insert another quarter"); } @Override public void ejectQuarter() { // 退回25分钱,并将状态转到未投入25分钱状态 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() { // 当前为已投入25分钱状态,还未转动曲柄,不能发放糖果 System.out.println("No gumball dispensed"); } }
/** * 售出状态 */ public class SoldState implements State { GumballMachine gumballMachine; public SoldState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { // 当前为售出状态,不能再次投入25分钱 System.out.println("Please wait, we're already giving you a gumball"); } @Override public void ejectQuarter() { // 当前为售出状态,不能退回25分钱 System.out.println("Sorry, you already truned 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.getGumballCount() > 0) { gumballMachine.setState(gumballMachine.getNoQuarterState()); } else { System.out.println("Oops, out of gumballs!"); gumballMachine.setState(gumballMachine.getSoldOutState()); } } }
/** * 售罄状态 */ public class SoldOutState implements State { GumballMachine gumballMachine; public SoldOutState(GumballMachine gumballMachine) { this.gumballMachine = gumballMachine; } @Override public void insertQuarter() { // 当前为售罄状态,不能投入25分钱 System.out.println("You can't insert a quarter, the machine is sold out"); } @Override public void ejectQuarter() { // 当前为售罄状态,不能要求退回25分钱 System.out.println("You can't eject, you haven't inserted a quarter yet"); } @Override public void turnCrank() { // 当前为售罄状态,不能转动曲柄 System.out.println("You turned, but there are no gumballs"); } @Override public void dispense() { // 当前为售罄状态,不能发放糖果 System.out.println("No gumball dispensed"); } }
public class Test { public static void main(String[] args) { // 糖果机 GumballMachine gumballMachine = new GumballMachine(5); // 正常操做 gumballMachine.insertQuarter(); gumballMachine.turnCrank(); System.out.println("-----------------------"); // 异常操做 gumballMachine.insertQuarter(); gumballMachine.ejectQuarter(); gumballMachine.turnCrank(); } }