侃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 Open和Time Out事件,所以这两个函数中进行状态的迁移操作,调用了CDoor对象中的ChangeState方法。其它的事件就忽略,只需写个空函数,什么事也不做。
从上面可以看到,利用State设计模式之后,代码变得更简单了,逻辑变得易于理解了,也容易扩展了。你不在会为看到一层层的if-else而感到头疼了。