设计模式之状态模式

状态模式(State),其含义是允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。书中的例子是Tcp连接的状态,处于Established,Listening,Closed等,当一个连接对象收到其他对象的请求时,根据自身的当前状态做出不用的反应。又或者一个人在心情不同的时候对待同一件事会有不同的做法。

其适用性:

一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为,

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

其结构图:

                           

 状态模式中的各种具体状态类,都实现了与Context的一个状态相关的行为,将每一个状态转换和动作封装到一个类中,就把着眼点从执行状态提高到整个对象的状态,Context将与状态相关的请求委托给State对象处理,当然也可以将自己当做参数传递给状态对象处理方法。同时State类也可以被context共享。

本文实现是通过在Handle方法中调用Context类中的changeState方法,而不是根据不同状态的情况作出不同的操作,使用一个方法处理不同状态,此方法的参数是个具体的状态类,较为简单,如下:

 package org.designpattern.behavioral.state;

public class Context {
    private State state;

    public Context(State state) {
        this.state = state;
    }
    public void request(){
        if(null != state){
            this.state.handle(this);
        }
    }

    public void changeState(State state){
        if(null != state){
            this.state = state;
        }
    }
}

  每个具体的状态类中,实现了抽象类State的Handle方法:

package org.designpattern.behavioral.state;

public class ConcreteStateA extends State {
    @Override
    public void handle(Context context) {
        //To change body of implemented methods use File | Settings | File Templates.
        System.out.println("handled by concreteStateA!");
        if(null != context){
            context.changeState(new ConcreteStateB());
        }
    }

} 

  具体的测试类中使用context发送请求,传递状态时都直接已知状态类型:

package org.designpattern.behavioral.state;

public class Main {
    public static void main(String[] args) {
        State state = new ConcreteStateA();
        Context context = new Context(state);
        context.request(); //handled by concreteStateA!
        context.request();   //handled by concreteStateB!
        context.request();  //handled by concreteStateA!
        context.request();   //handled by concreteStateB!

    }

} 

 状态模式主要用与控制一个对象状态切换的条件表达式过于复杂的情况。它通过把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简单化。

posted on 2013-08-04 22:16  糊涂先生  阅读(315)  评论(0编辑  收藏  举报