一、状态模式的核心思想
状态模式的核心思想:在对象的状态改变时,会同时改变其行为。比如使用 MSN、QQ等可以切换不同的状态,例如在线、隐身、忙碌、离开、空闲等,在不同的状态下你可以做不同的事情,例如在线时可以收发文件,而隐身时就不能收发文件等,当你每次设定确认你的状态后,你的状态信息就会显示给你的好友。这就不难理解什么状态模式了。
在状态模式中,状态是核心,因为状态的改变而引起的行为的改变则是状态模式的用意所在。因此,在状态模式中需要包含如下两种对象。
- 状态类 State:它自身包含了状态变量 value,并提供了根据状态变量的不同值进行切换的操作函数。
- 状态切换类 Context:它负责根据 State 的不同状态来切换不同的调用,状态模式结构图如下图所示。
下面来看具体的实现。
(1) 状态类 State.java首先包含了一个代表其自身状态的变量 vaue,并提供getter/setter 来修改和取得该变量的值。同时,它需要提供多种操作方法,以对应不同状态下的行为。其源代码如下程序所示。
package behavior.state;
/**
* @author Minggg
* 状态类
*/
public class State {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void operation1() {
System.out.println("执行操作 1");
}
public void operation2() {
System.out.println("执行操作 2");
}
}
(2) 状态切换类 Context.java包含一个 State 的变量 state 的引用,它会根据 state 的状态值 value来决定调用哪种函数。其源代码如下程序所示。
package behavior.state;
/**
* @author Minggg
* 状态切换类
*/
public class Context {
private State state;
public Context(State state) {
this.state = state;
}
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
public void operation(){
if (state.getValue().equals("type1")){
state.operation1();
} else if (state.getValue().equals("type2")){
state.operation2();
}
}
}
下面我们就可以创建一个 State的对象 state,并将其添加到 Context中。然后设置不同的状态,分别调用 context 的 operation()函数,就可以实现对不同状态下的行为的改变。其源代码如下程序所示。
package behavior.state;
public class Test {
public static void main(String[] args){
State state = new State();
Context context = new Context(state);
// 设置第一种状态
state.setValue("type1");
context.operation();
// 设置第二种状态
state.setValue("type2");
context.operation();
}
}
运行该程序输出如下信息:
执行操作 1
执行操作 2
它表明我们在改变了 State 的状态后,其行为被 Context动态地进行了切换,这正是状态模式的用意。
二、何时使用状态模式
状态模式在实际使用中比较多,适合状态的切换。因为我们经常会使用If else if else进行状态切换,如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取状态模式了。
不只是根据状态,也有根据属性的情况。如果某个对象的属性不同,对象的行为就不一样,这点在数据库系统中出现频率比较高,我们经常会在一个数据表的尾部,加上property属性含义的字段,用以标识记录中一些特殊性质的记录,这种属性的改变又是随时可能发生的,就有可能要使用状态模式。
三、Java 中的应用–Java 工作流引擎
状态模式在工作流或游戏等各种系统中大量使用,甚至是这些系统的核心功能设计,例如政府OA 中,一个批文的状态有多种:未办、正在办理、正在批示、正在审核、已经完成等各种状态,使用状态机可以封装这个状态的变化规则,从而达到扩充状态时,不必涉及到状态的使用者。
工作流系统的核心部分是工作流引擎,引擎是驱动流程流动的主要部件,它负责解释工作流流程定义、创建并初始化流程实例、控制流程流动的路径、记录流程运行状态,挂起或唤醒流程、终止正在运行的流程、与其他引擎之间通信等工作。
工作流通常用于以下各种业务系统中。
- 业务流程辅助办公软件:不同行业者有各自独立的业务流程,使用一些业务流程管理软件可以提高流程效率并降低出错率,比如审批类、办公类、采购类、MSI、电子商务、电子政务、电子法务,以及需要按一定的业务流程办公的所有领域的办公辅助系统中都可以使用工作流。
- 软件内部工作的顺序控制:很多时候,在不涉及业务的情况下,对软件的自身协调控制也有很复杂的流程,比如一个需要设置很多参数的软件安装向导、一个窗体内各控件间复杂的锁定关系、一个软件中多个窗体相互调用的顺序都可以用工作流实现。
- 自动筛选查询类系统:比如招投标系统中的自动开标模块、考生录取系统中的自动投档模块、搜索引擎的自动分析模块,可以使用工作流管理这些模块的运算方案与运算路径。
- 自动化控制系统:在工控系统中,有时需要用一个顺序对一系列的机器进行控制,这时可以使用工作流管理这些控制。
其中的第一项是目前工作流系统应用最为广泛的,通常在办公自动化系统(OA)中应用最为广泛,凡是涉及到行政审批等方面的业务流程,都必须采用工作流来进行开发。
常用的工作流引擎如jBPM、OSWorkflow、Shark、OFBiz、Werkflow、Willow等,其中jBPM是功能强大的引擎,OSWorkflow是使用最简单的引擎。