小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的处理是复杂的。