设计模式笔记之状态模式

来源:互联网 发布:机器人算法工程师 编辑:程序博客网 时间:2024/06/07 05:38

定义

状态模式允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。状态模式将状态封装成独立的类,并将动作委托到代表当前状态的对象,这样类的行为就随着状态的改变而变化。

让我们通过类图来进一步理解状态模式。

类图


(2-1)

状态模式将一群行为封装到状态对象中,Context通过委托让具体的状态对象执行操作。如果Context中的状态发送改变,Context中的行为也会发生改变。而且Context的客户端不用关心状态对象,也不用关心Context中的状态何时改变。

代码实现

在这里引用headfirst中的例子阐述怎样用代码实现状态模式。

图(3-1)是一个糖果机器的状态图,从图中我们可以了解到糖果机总共有投币、退币、摇杆、出糖果、放糖果五个操作,有币、无币、销售糖果、售罄四种状态。


(3-1)

参考上文中的状态模式定义和类图,我们抽象出了糖果机的四种状态和五种行为,接下来我们需要将糖果机的行为封装到状态对象中,让糖果机通过委托的方式调用不同的状态执行对应的操作。

package cn.lzz.state;/** * 所有状态对应的统一接口 * @author lizhizhou * */public interface State {/** * 投币 */public void insertQuarter();/** * 退币 */public void ejectQuarter();/** * 摇动摇杆 */public void turnGrank();/** * 出糖果 */public void dispence();}

package cn.lzz.state;import java.util.Random;/** * 有币状态 * @author lizhizhou * */public class HasQuarterState implements State {private GumballMachine gumballMachine;private Random random=new Random();public HasQuarterState(GumballMachine gumballMachine){this.gumballMachine=gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("You can't insert another quarter");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("Quarter retured");gumballMachine.setState(gumballMachine.getNoQuarterState());}@Overridepublic void turnGrank() {// TODO Auto-generated method stubSystem.out.println("You turn....");gumballMachine.setState(gumballMachine.getSoldState());}@Overridepublic void dispence() {// TODO Auto-generated method stubSystem.out.println("No gumballs dispensed");}}

package cn.lzz.state;/** * 无币状态 * @author lizhizhou * */public class NoQuarterState implements State {private GumballMachine gumballMachine;public NoQuarterState(GumballMachine gumballMachine){this.gumballMachine=gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("You inserted a quarter.");gumballMachine.setState(gumballMachine.getHasQuarterState());}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("You haven't insertered a quarter.");}@Overridepublic void turnGrank() {// TODO Auto-generated method stubSystem.out.println("You turned,but there is no quarter.");}@Overridepublic void dispence() {// TODO Auto-generated method stubSystem.out.println("You need to pay first.");}}

package cn.lzz.state;/** * 售罄状态 * @author lizhizhou * */public class SoldOutState implements State{private GumballMachine gumballMachine;public SoldOutState(GumballMachine gumballMachine){this.gumballMachine=gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stubSystem.out.println("Sorry,There isn't any gumball.");}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stubSystem.out.println("There is no any quarter.");}@Overridepublic void turnGrank() {// TODO Auto-generated method stubSystem.out.println("Pleans,Don't turn grank.");}@Overridepublic void dispence() {// TODO Auto-generated method stubSystem.out.println("Sorry,There isn't any gumball.");}}

package cn.lzz.state;/** * 销售状态 * @author lizhizhou * */public class SoldState implements State {private GumballMachine gumballMachine;public SoldState(GumballMachine gumballMachine){this.gumballMachine=gumballMachine;}@Overridepublic void insertQuarter() {// TODO Auto-generated method stub}@Overridepublic void ejectQuarter() {// TODO Auto-generated method stub}@Overridepublic void turnGrank() {// TODO Auto-generated method stub}@Overridepublic void dispence() {// TODO Auto-generated method stubgumballMachine.releaseBall();if(gumballMachine.getCount()>0){gumballMachine.setState(gumballMachine.getNoQuarterState());}else{gumballMachine.setState(gumballMachine.getSoldOutState());}}}

package cn.lzz.state;/** * 糖果机 * @author lizhizhou * */public class GumballMachine {//售罄private State soldOutState;//没有硬币private State noQuarterState;//有硬币private State hasQuarterState;//销售状态private State soldState;private State state=soldOutState;private int count=0;/** * 初始化糖果机 * @param numbersGumball */public GumballMachine(int numbersGumball){this.soldOutState=new SoldOutState(this);this.noQuarterState=new NoQuarterState(this);this.hasQuarterState=new HasQuarterState(this);this.soldState=new SoldState(this);this.count=numbersGumball;if(numbersGumball>0){this.state=this.noQuarterState;}}/** * 投币 */public void insertQuarter(){state.insertQuarter();}/** * 退币 */public void ejectQuarter(){state.ejectQuarter();}/** * 转动摇杆 */public void turnGrank(){state.turnGrank();state.dispence();}/** * 出糖果 */public void releaseBall(){System.out.println("A gumball comes rolling out the solt.....");if(count>0){count=count-1;}}/** * 放入糖果 * @param count */public void refill(int count){if(count>0){this.count+=count;this.state=this.noQuarterState;}}public State getState() {return state;}public void setState(State state) {this.state = state;}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 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;}@Overridepublic String toString() {if(this.state==this.noQuarterState){return "GumballMachine is wating for quarter.";}else if(this.state==this.hasQuarterState){return "GumballMachine has quarter.";}else if(this.state==this.soldOutState){return "GumballMachine has been soldOut.";}else if(this.state==this.soldState){return "GumballMachine is solding gumball.";}else{return "Hello";}}}

package cn.lzz.state;/** * 测试代码 * @author lizhizhou * */public class GumballMachineTestDrive {public static void main(String[] args) {GumballMachine gumballMachine=new GumballMachine(10);System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnGrank();System.out.println(gumballMachine);gumballMachine.insertQuarter();gumballMachine.turnGrank();gumballMachine.insertQuarter();gumballMachine.turnGrank();System.out.println(gumballMachine);}}

执行结果:

GumballMachine is wating for quarter.You inserted a quarter.You turn....A gumball comes rolling out the solt.....GumballMachine is wating for quarter.You inserted a quarter.You turn....A gumball comes rolling out the solt.....You inserted a quarter.You turn....A gumball comes rolling out the solt.....GumballMachine is wating for quarter.



原创粉丝点击