您的位置:首页 > 其它

设计模式总结-State模式

2012-09-11 15:50 218 查看
设计模式总结-State模式
注:本文多处引用了WWW.jdon.com网站的《State模式》一文,原文前参见:http://www.jdon.com/designpatterns/designpattern_State.htm

一、State模式定义:



不同的状态,不同的行为;或者说,每个状态有着相应的行为.

二、State模式的适用场合:



State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If elseif else 进行状态切换, 如果针对状态的这样判断切换反复出现,我们就要联想到是否可以采取State模式了.

三、State模式与Command模式的比较:



前者从调用者和被调用者的角度出发,目的是封装被调用者的行为,让调用者只和统一的顶层接口打交道。后者从对象自身的状态出发,不涉及调用者和被调用者。是对象自身的状态切换导致的行为变化。

四、“开关切换状态” 和“ 一般的状态判断”区别:

“开关状态切换”经常发生在GUI界面的交互过程中,通过结合对象当前状态和参数,判断接下来对象应该切换到什么状态。被判断对象和被更新对象都是同一个。这一点和“一般的状态判断”是不同的,后者是根据其它对象或属性的值来更新自身的状态。被判断对象和被更新对象不是同一个。

例如:if (which==1) state="hello";

   else if (which==2) state="hi";

   else if (which==3) state="bye";

这是一个 " 一般的状态判断",state值的不同是根据which变量来决定的,which和state没有关系.如果改成:

if (state.euqals("bye")) state="hello";

else if (state.euqals("hello")) state="hi";

else if (state.euqals("hi")) state="bye";

这就是 "开关切换状态",是将state的状态从"hello"切换到"hi",再切换到""bye";再切换到"hello",好象一个旋转开关,这种状态改变就可以使用State模式了.

五、State模式的构成:



1.state manager 状态管理器,就是开关,如上面例子的Context实际就是一个state manager, 在state manager中有对状态的切换动作.

2.用抽象类或接口实现的父类,,不同状态就是继承这个父类的不同子类(也就是不同的状态行为)

六、State模式的例子:

状态机--父类定义


public abstract class State{ // 状态行为的父类




// 状态机需要能够感知上下文的情况,也就是之前的状态和目前的情形,所以用Context作为参数


public abstract void handlepush(Context c);


  public abstract void handlepull(Context c);



  public abstract void 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)}




}

特点:

·拥有一个父类,表示各种不同的状态。该父类具有三个典型的方法:

·切换到上一个状态

·切换到下一个状态

·获取当前状态

·拥有一至多个子类,在子类中实现具体的状态向前、向后的切换

·如果把每个状态看成一个“状态链”上的一个独立的节点,那么有N个状态,则需要N个子类。

·如果状态只支持单向切换,则除了首尾两个状态,其它状态的节点均有两个方法,分别是向前/后一个状态的切换

·如果状态支持双向切换(例如MP3的自动循环播放功能),则尾节点可以有两个状态切换的方法

状态机管理器


public class Context{




  private Sate state=null; //我们将原来的 Color state 改成了新建的State state;




  //setState是用来改变state的状态 使用setState实现状态的切换,不同的状态传入不同的State,都是State的子类


  pulic void setState(State state){


    this.state=state;


}




  public void push(){


//状态的切换的细节部分,在本例中是颜色的变化,已经封装在子类的handlepush中实现,这里无需关心


    [b]state.handlepush(this);

[/b]

    


    //因为sample要使用state中的一个切换结果,使用getColor()


    Sample sample=new Sample(state.getColor());


    sample.operate();


}




  public void pull(){


[b]state.handlepull(this);[/b]


    Sample2 sample2=new Sample2(state.getColor());


    sample2.operate();




  }




}

特点:

·拥有一个状态机对象:用于代表当前的状态

·拥有一个切换到上/下一个状态的方法:实际上是调用了状态机自身的切换方法,由于状态机本身已经“知道”自己是什么状态,所以可以方便的切换到上、下一个状态。例如:state.handlePush(this)这个方法,由于此时state对象是什么类型已经知道(通过对管理器中的状态机赋值),所以切换工作就交给了对象本身了,调用者不需要知道内部是如何切换的。

·拥有一个获取当前状态的方法

我们可以看到,在状态机的上下文中,push和pull方法都把上下文本身作为参数传递给状态机,然后在状态机中调用了上下文的setState(Context c)方法。这是一个典型的Call-back(回调)机制。

七、状态机模式的优点:



(1) 封装转换过程,也就是转换规则

(2) 枚举可能的状态,因此,需要事先确定状态种类。

使用状态模式后,客户端外界可以直接使用事件Event实现,根本不必关心该事件导致如何状态变化,这些是由状态机等内部实现。这是一种Event-condition-State,状态模式封装了condition-State部分。

每个状态形成一个子类,每个状态只关心它的下一个可能状态,从而无形中形成了状态转换的规则。如果新的状态加入,只涉及它的前一个状态修改和定义。

十、状态模式和其它模式的结合应用:



从状态模式的实质:“只关心它的下一个可能状态”和客户端使用特点:“使用事件Event实现”来看,我们可以考虑将观察者模式(Observer)和状态模式(State)结合起来。被观察者在改变时发送广播消息(Event事件),观察着注意并接收该消息后,使用状态机来对当前应用的上下文进行状态的切换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: