源码工作室

目标:通俗的语言说出通俗的技术
  博客园  :: 首页  :: 新随笔  :: 联系 :: 管理

侃State模式

Posted on 2005-10-24 17:32  源码工作室  阅读(1909)  评论(2编辑  收藏  举报
State模式

作用:
       允许一个对象在其内部状态改变时改变它的行为。
  
    避免if语句嵌套过深或过于复杂,易添加新的状态。
正文:
       State模式是一种有限状态机,它很好的解决了if语句嵌套过深或过于复杂,能容易理清状态之间的复杂逻辑,就是“何时干何事”。而且很容易的添加新的状态或修改原有的状态。
       State模式中,一个事件会引起状态的迁移。
       让我们来看一个关于安全防盗门例子。状态图如下:

让我们先列出状态的迁移情况,假设初始时处于NatualClosed状态。

1.         当主人用钥匙打开门时,从NaturalClosed->NatualOpened

2.         当主人进入家里,关门,从NaturalOpened->NatualClosed

3.         如果没有关门,持续五分钟,门自动关闭,从NaturalOpened->NatualClosed

4.         如果有小偷撬锁非法进入,从NaturalClosed->ForcibleOpened

5.         检测到非法进入,从ForcibleOpened->ForcibleClosed,这时门从内外都不能再打开。

6.         通过输入正确的密码,可以解除死锁状态,ForcibleClosed -> NatualOpened

而事件类别为:

1.         正常打开,Natural Open事件。

2.         正常关闭,Natural Close事件。

3.         强制打开,Forcible Open事件。

4.         强制关闭,Forcible Close事件。

5.         自动正常关闭,Time Out事件。

6.         密码解锁,Password Open事件。
UML图如下:

 

       S t a t e模式将每一个条件分支放入一个独立的类中,在例子中有四种状态,就有四个状态类。在CDoor类中包含一些事件函数,还要一个CDoorState的对象。在这些事件函数中直接调用m_pState的对应函数。比如

CDoor::NaturalOpen()
{
       m_pState->NaturalOpen(this);
}

       在调用中,把CDoor对象指针传给没CDoorState对象。然后状态就在各自的状态类中改变。在CNaturalOpenedState状态时,根据前面的分析,它会响应两个事件,Natural OpenTime Out事件,所以这两个函数中进行状态的迁移操作,调用了CDoor对象中的ChangeState方法。其它的事件就忽略,只需写个空函数,什么事也不做。

       从上面可以看到,利用State设计模式之后,代码变得更简单了,逻辑变得易于理解了,也容易扩展了。你不在会为看到一层层的if-else而感到头疼了。