Intent:
Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.
当一个对象内部状态发生变化时,他的行为也将发生变化,在该模式下,该对象会转变成另外一个对象。
由简单的开始会比较好理解状态模式的作用,先来看一个例子,如果您有一个只能顺时针转动的瓦斯开关,转动一次的状态为off、 small fire、medium fire与large fire,您如何在程式中控制状态的变化与行为呢?一个最简单的方式就是用if..else或是switch流程来控制,例如:
State.java
public class State {
private int state;
public State() {
state = 0;
}
public void switchFire() {
if (state == 0) {
state = 1;
System.out.println( "small fire" );
} else if (state == 1) {
state = 2;
System.out.println( "medium fire" );
} else if (state == 2) {
state = 3;
System.out.println( "large fire" );
} else {
state = 0;
System.out.println( "turning off" );
}
}
}
Main.java
public class Main {
public static void main(String[] args) {
State state = new State();
state.switchFire();
state.switchFire();
state.switchFire();
state.switchFire();
}
}
上面的例子,State一个类处理了所有的状态变化以及变化后的行为,State模式就是要把状态变化以及相应的行为绑定,并把不同的变化阶段进行解耦,看到这,设计模式来自于代码重构的过程中。
解耦后的代码如下:
IState.java
public interface IState {
public void switchFire(FireSwitch sw);
}
OffState
public class OffState implements IState {
public void switchFire(FireSwitch sw) {
sw.setState(new SmallState());
System.out.println( "small fire" );
}
}
SmallState.java
public class SmallState implements IState {
public void switchFire(FireSwitch sw) {
sw.setState(new MediumState());
System.out.println( "medium fire" );
}
}
MediumState.java
public class MediumState implements IState {
public void switchFire(FireSwitch sw) {
sw.setState(new LargeState());
System.out.println( "large fire" );
}
}
LargeState.java
public class LargeState implements IState {
public void switchFire(FireSwitch sw) {
sw.setState(new OffState());
System.out.println( "off fire" );
}
}
FireSwitch.java
public class FireSwitch {
private IState current;
public FireSwitch() {
current = new OffState();
}
public void setState(IState s) {
current = s;
}
public void switchFire() {
current.switchFire(this);
}
}
Main.java
public class Main {
public static void main(String[] args) {
FireSwitch fireSwitch = new FireSwitch();
fireSwitch.switchFire();
fireSwitch.switchFire();
fireSwitch.switchFire();
fireSwitch.switchFire();
}
}
一般的:

其中的状态值,作为驱动整个模式的数据,仍然通过数据把各个对象耦合在一起。
参与者:
- Context:
定义客户端调用的接口
维护一个ConcreteState对象来定义当前的状态
- State
定义封装参与者Context的ConcreteState的状态与对应的行为
- ConcreteState
具体的各个状态对应的ConcreteState对象
体会:
Spring的controller用时候用的就是这个模式
该模式实现了对象“独立”维护自己的行为,根据状态的情况,就是一个状态自动机
状态模式实质:
使用状态模式前,客户端外界需要介入改变状态,而状态改变的实现是琐碎或复杂的。
使用状态模式后,客户端外界可以直接使用事件Event实现,根本不必关心该事件导致如何状态变化,这些是由状态机等内部实现。
这是一种Event-condition-State,状态模式封装了condition-State部分。
每个状态形成一个子类,每个状态只关心它的下一个可能状态,从而无形中形成了状态转换的规则。如果新的状态加入,只涉及它的前一个状态修改和定义。
状态转换有几个方法实现:一个在每个状态实现next(),指定下一个状态;还有一种方法,设定一个StateOwner,在StateOwner设定stateEnter状态进入和stateExit状态退出行为。
状态从一个方面说明了流程,流程是随时间而改变,状态是截取流程某个时间片。
文献:
http://www.riabook.cn/doc/designpattern/StatePattern.htm
http://www.jdon.com/designpatterns/designpattern_State.htm