第169章(1 / 1)

大话设计模式 吴强 892 字 2个月前

小A:“如何使用状态模式?”

大B:“状态模式可以允许客户端改变状态的转换行为,而状态机则是能够自动改变状态,状态机是一个比较独立的而且复杂的机制,具体可参考一个状态机开源项目:状态模式在工作流或游戏等各种系统中有大量使用,甚至是这些系统的核心功能设计,例如政府OA中,一个批文的状态有多种:未办;正在办理;正在批示;正在审核;已经完成等各种状态,使用状态机可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状态的使用者。在网络游戏中,一个游戏活动存在开始;开玩;正在玩;输赢等各种状态,使用状态模式就可以实现游戏状态的总控,而游戏状态决定了游戏的各个方面,使用状态模式可以对整个游戏架构功能实现起到决定的主导作用。State需要两种类型实体参与:1、statemanager状态管理器,就是开关,如上面例子的Context实际就是一个statemanager在statemanager中有对状态的切换动作。2、用抽象类或接口实现的父类,不同状态就是继承这个父类的不同子类。”

以上面的Context为例。我们要修改它,建立两个类型的实体。

第一步:

首先建立一个父类:

publicabstractclassState{

publicabstractvoidhandlepush(Contextc);

publicabstractvoidhandlepull(Contextc);

publicabstractvoidgetcolor();

}

父类中的方法要对应statemanager中的开关行为,在statemanager中这个例子就是Context中,有两个开关动作push推和pull拉。那么在状态父类中就要有具体处理这两个动作:handlepush()handlepull();同时还需要一个获取push或pull结果的方法getcolor()。

下面是具体子类的实现:

publicclassBlueStateextendsState{

publicvoidhandlepush(Contextc){

//根据push方法“如果是blue状态的切换到green”;

c.setState(newGreenState());

}

publicvoidhandlepull(Contextc){

//根据pull方法“如果是blue状态的切换到red”;

c.setState(newRedState());

}

publicabstractvoidgetcolor(){return(Color.blue)}

}

同样其他状态的子类实现如blue一样。

第二步:

要重新改写Statemanager也就是本例的Context:

publicclassContext{

privateSatestate=null;//我们将原来的Colorstate改成了新建的Statestate;

//setState是用来改变state的状态使用setState实现状态的切换

pulicvoidsetState(Statestate){

this.state=state;

}

publicvoidpush(){

//状态的切换的细节部分,在本例中是颜色的变化,已经封装在子类的handlepush中实现,这里无需关心

state.handlepush(this);

//因为sample要使用state中的一个切换结果,使用getColor()

Samplesample=newSample(state.getColor());

sample.operate();

}

publicvoidpull(){

state.handlepull(this);

Sample2sample2=newSample2(state.getColor());

sample2.operate();

}

}

至此,我们也就实现了State的refactorying过程。

以上只是相当简单的一个实例,在实际应用中,handlepush或handelpull的处理是复杂的。