书城计算机大话设计模式
11030400000169

第169章 10 如何使用状态模式

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

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

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

第一步:

首先建立一个父类:

public abstract class State{

public abstract void handlepush(Context c);

public abstract void handlepull(Context c);

public abstract void getcolor();

}

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

下面是具体子类的实现:

public class BlueState extends State{

public void handlepush(Context c){

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

c。setState(new GreenState());

}

public void handlepull(Context c){

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

c。setState(new RedState());

}

public abstract void getcolor(){return(Color。blue)}

}

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

第二步:

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

public class Context{

private Sate state=null;//我们将原来的Color state 改成了新建的State state;

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

pulic void setState(State state){

this。state=state;

}

public void push(){

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

state。handlepush(this);

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

Sample sample=new Sample(state。getColor());

sample。operate();

}

public void pull(){

state。handlepull(this);

Sample2 sample2=new Sample2(state。getColor());

sample2.operate();

}

}

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

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