Writen by Fox(yulefox.at.gmail.com)

State模式对应到C++的多态特性。

State模式适用较广,这儿给出比较常见易懂的两种情况:

1. 当怪物在面对不同职业和特性的玩家时对应不同的AI处理和技能释放:

CSkill* pAttackSkill;

if( pPlayer->MagicImmune() ) pAttackSkill = SomePhysicalAttackSkill;

else if( pPlayer->PhysicalImmune() ) pAttackSkill = SomeMagicAttackSkill;

pAttackSkill->Begin();

或者使用分支结构:

CSkill* pAttackSkill;

switch( pPlayer->GetOccupation() )

{

  case WARRIOR: pAttackSkill = SomeLongRangeSkill; break;

  case MAGICIAN: pAttackSkill = SomeForceSkill; break;

  case NIMROD: pAttackSkill = SomeMagicSkill; break;

}

pAttackSkill->Begin();

2. 我们也可以封装一个显式的转换接口:

CSkill* pAttackSkill;

pMonster->ChangeState(pPlayer->GetOccupation(), PAttackSkill);

pMonster->Attack();

这儿的CSkill类就是所谓的State,作为怪物的一个行为被封装,并因为各种上下文的不同而被赋予不同的实例。

上面提到的是State模式的一些使用方法并不严谨,却可以为我们探究State模式的特性打下很好的一个基础。

既然称为状态模式,我们可以将其与状态机联系起来,二者的共同之处在于状态转换状态模式中各状态之间即存在一定的转换关系,这种转换关系可以像上面的例子那样放在上下文中,也可以放到各状态中。仍以怪物AI为例,一般情况下怪物的状态转换关系如下:

Init->Find->Attack->Defence->Hurt->Dead->Relive

这些状态的某些状态之间存在多种转换,但即使是多种转换也是可以确定的,比如一个怪物只有活着并且没有被攻击(我们认为被攻击时敌人就是攻击者,不需要附加寻找状态,虽然攻击者的确定可能会复杂些)的情况下才会寻找敌人,如果怪物不是被攻击(我们认为被驯服、被诅咒、被染病都属于被攻击)的话,不会防御、受伤和死亡(被服务器Kill掉例外),如果怪物没有死亡的话也不会被复活,等等。

这样一来,状态的转换就可以放到各具体状态内部去触发,这更符合状态模式的意图本身,而状态在内部还是外部被触发和转换是没有太大区别的,因此上面讲到的例子还是可以说明这一点。

其他应用包括像:

根据服务器的不同状态确定客户端的不同行为转换:Create->Bind->Listen->Accept->Recv->Send;

根据用户的不同操作实现特定的效果或行为转换等:Select->Attack->Gain->Hurt->Dead->Relive。

状态模式本身并不复杂,抽象出各状态及其转换关系并设计出完整、合理、易扩展的模型更重要。

在学习设计模式时,也有这样一个状态模型:

读懂模式的结构->思考模式的意图->构建模式的模型->拓展模式的应用

之所以看过会忘,也是因为你对这样一个状态转换还没有达到完整、合理、扩展的要求。


相关链接:

设计模式(一): http://www.yulefox.com/index.php/20080806/design-patterns-01.html/

Wikipedia: http://en.wikipedia.org/wiki/State_pattern

Source Making: http://sourcemaking.com/design_patterns/state

Data & Object Factory: http://www.dofactory.com/Patterns/PatternState.aspx


最近一直在加班,同事在看我Blog的时候,说我的设计模式只写了一篇就没了下文。我不好意思的解释说忙,系列的文章写起来累,而且我对设计模式说不上融会贯通,怕误导别人,也怕被骂。

但这个系列的确是我非常想写完的一个系列,所以就在这儿补上,慢慢补吧,毕竟欠下的还多的很。

但为了节省时间,我能不写代码就不写代码了,尽量把模式介绍清楚就是了。

相关阅读

转载注明:游戏人生(http://www.yulefox.com/)
联系作者:
引用通告:http://www.yulefox.com/20081119/design-patterns-02.html/trackback/

发表回复