状态( State )模式:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

适用性:

  • 一个对象的行为取决于它的状态, 并且它必须在运行时刻根据状态改变它的行为。
  • 一个操作中含有庞大的多分支的条件语句,且这些分支依赖于该对象的状态。这个状态通常用一个或多个枚举常量表示。通常, 有多个操作包含这一相同的条件结构。State模式将每一个条件分支放入一个独立的类中。这使得你可以根据对象自身的情况将对象的状态作为一个对象,这一对象可以不依赖于其他对象而独立变化。

所涉及的角色:

抽象状态 (State) 角色:定义一个接口,用以封装对象的一个特定状态所对应的形为。

具体状态 (Concrete State) 角色:每一个具体状态类都实现环境( Context )的一个状态所对应的行为。

环境( Context )角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例。这个具体状态类的实例给出些环境对象的现有状态。
state.bmp
一个简单的例子:

抽象状态State类

package  State;

public   interface  State {
    
// 接口方法
     void  operator();
}


具体状态类ConcreteStateA和ConcreteStateB:

package  State;

public   class  ConcreteStateA  implements  State {
    
// 实现接口方法
     public   void  operator() {
        System.out.println(
" The ConcreteStateA " );
    }

}
package  State;

public   class  ConcreteStateB  implements  State {
    
// 实现接口方法
     public   void  operator() {
        System.out.println(
" The ConcreteStateB " );
    }

}

环境Context类
package State;

public class Context{
    
private State state;
    
//状态赋值方法
    public void setState(State state){
        
this.state=state;
    }

    
//委派方法
    public void operator(){
        state.operator();
    }

}
客户端类:
package State;

public class Client{
    
private static State state=null;
    
private static Context context=null;
    
    
public static void main(String[] args){
        
        context
=new Context();
        state
=new ConcreteStateA();
        context.setState(state);
        context.operator();
        state
=new ConcreteStateB();
        context.setState(state);
        context.operator();
    }

}

状态模式与策略模式的区别:

两个模式很容易混淆,区别两者的一个方法是考察环境角色是否有明显的状态和状态过渡。如果环境角色只有一个状态,那么就应当使用策略模式。策略模式的特点:一旦环境角色选择了一个具体的策略类,那么在整个环境类的生命周期里它都不会改变这个具体策略类。而状态模式则适用另一情况,即环境角色有明显的状态转移。在环境类的生命周期里面,会有几个不同的状态被使用。

另外一个微妙的区别在于策略模式的环境自己选择一个具体的策略类,而状态模式的环境类是被外在原因放进一个具体的状态中。

策略模式所选择的策略类往往不明显的告诉客户端它所选择的具体策略类,而状态模式则相反,环境角色所处的状态是明显告诉客户端的。

参考资料:《java与模式》
《设计模式速查手册》
http://blog.csdn.net/qutr/archive/2006/08/01/1007617.aspx