狀態模式容許對象在內部狀態改變時改變它的行爲,對象看起來好像修改了它的類。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(); } }