《游戏编程模式》一7.4 状态模式

7.4 状态模式

对于熟知面向对象方法的人来说,每一个条件分支都可以用动态分发来解决(换句话说,都可以用C++里面的虚函数来解决)。但是,如果这样做,你可能会把简单问题复杂化。有时候,一个简单的if语句就足够了。

状态模式的由来也有一些历史原因。许多面向对象设计的拥护者—— GoF和重构的作者Martin Fowler都是Smalltalk出身。在那里,如果有一个ifThen语句,我们便可以用一个表示true和false的对象来操作。
但是,在我们这个例子当中,我们发现面对对象设计也就是状态模式更合适。

GoF描述的状态模式在应用到我们的例子中时如下。

7.4.1 一个状态接口

首先,我们为状态定义一个接口。每一个与状态相关的行为都定义成虚函数。在我们的例子中,就是handleInput()和update()函数。

class HeroineState
{
public:
 virtual ~HeroineState() {}
 virtual void handleInput(Heroine& heroine,
                Input input) {}
 virtual void update(Heroine& heroine) {}
};

7.4.2 为每一个状态定义一个类

对于每一个状态,我们定义了一个类并继承此状态接口。它的方法定义主角对应此状态的行为。换句话说,把之前的switch语句里面的每一个case语句里的内容放置到它们对应的状态类里面去。比如:

class DuckingState : public HeroineState
{
public:
 DuckingState()
 : chargeTime_(0)
 {}

 virtual void handleInput(Heroine& heroine,
                Input input) {
  if (input == RELEASE_DOWN)
  {
   // Change to standing state...
   heroine.setGraphics(IMAGE_STAND);
  }
 }

 virtual void update(Heroine& heroine) {
  chargeTime_++;
  if (chargeTime_ > MAX_CHARGE)
  {
   heroine.superBomb();
  }
 }

private:
 int chargeTime_;
};

注意,我们这里chargeTime_从Heroine类中移到了DuckingState(躲避状态)类中。这样非常好,因为这个变量只是对躲避状态有意义,现在把它定义在这里,正好显式地反映了我们的对象模型。

7.4.3 状态委托

接下来,我们在主角类中定义一个指针变量,让它指向当前的状态。我们把之前那个很大的switch语句去掉,并让它去调用状态接口的虚函数,最终这些虚方法就会动态地调用具体子状态的相应函数。

状态委托看起来很像策略模式和类型对象模式(第13章)。在这三个模式中,你会有一个主对象委托给另外的附属对象。它们三者的区别主要在于目的不同:

策略模式的目标是将主类与它的部分行为进行解耦。
类型对象模式的目标是使得多个对象通过共享相同类型对象的引用来表现出相似性。
状态模式的目标是通过改变主对象代理的对象来改变主对象的行为。

class Heroine
{
public:
 virtual void handleInput(Input input)
 {
  state_->handleInput(*this, input);
 }

 virtual void update() { state_->update(*this); }

 // Other methods...
private:
 HeroineState* state_;
};

为了修改状态,我们需要把state_指针指向另一个不同的HeroineState状态对象。至此,我们的状态模式就讲完了。

时间: 2024-09-20 09:50:34

《游戏编程模式》一7.4 状态模式的相关文章

从工作流状态机实践中总结状态模式使用心得

 作者:banq 发表时间:2003年12月07日 00:10 回复 原贴网址:http://www.jdon.com/jivejdon/thread/10981.html   状态模式好像是很简单的模式,正因为状态好像是个简单的对象,想复杂化实现设计模式就不是容易,误用情况很多. 我个人曾经设计过一个大型游戏系统的游戏状态机,游戏状态可以说是游戏设计的主要架构,但是由于系统过分复杂和时间仓促,并没有真正实现状态模式. 目前在实现一个电子政务项目中,需要进行流程状态变化,在电子政务设计中,我发现

设计模式 ( 十七) 状态模式State(对象行为型)

设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得"力不从心了".随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的

学习php设计模式 php实现状态模式_php技巧

一.意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类 状态模式变化的位置在于对象的状态 二.状态模式结构图   三.状态模式中主要角色抽象状态(State)角色:定义一个接口,用以封装环境对象的一个特定的状态所对应的行为 具体状态(ConcreteState)角色:每一个具体状态类都实现了环境(Context)的一个状态所对应的行为 环境(Context)角色:定义客户端所感兴趣的接口,并且保留一个具体状态类的实例.这个具体状态类的实例给出此环境对象的现有状态四.状态

iOS App的设计模式开发中对State状态模式的运用_IOS

1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得"力不从心了".随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的模式. 例子1:按钮来控制一个电梯的状态,一个电梯开们,

设计模式之禅之设计模式-状态模式

一:状态模式定义        --->当一个对象内在状态改变时允许其改变行为,这个对象看起来像改变了其类        --->状态模式的核心是封装,状态的变更引起了行为的变更,从外部看起来就好像这个对象对应的类发生了改变一样        --->状态模式相对来说比较复杂,它提供了一种对物质运动的另一个观察视角,通过状态变更促使行为的变化,就类似水的状态变更一样,一碗水的初始状态是液态,通过加热转变为气态,状态的改变同时也引起体积的扩大,然后就产生了一个新的行为:鸣笛或顶起壶盖,瓦特

《游戏编程模式》一第7章 状态模式

第7章 状态模式 "允许一个对象在其内部状态改变时改变自身的行为.对象看起来好像是在修改自身类." 交代一下:我写的有些过头了,我在本章里面添加了太多东西.表面上这一章是介绍状态模式[1]的,但是我不能抛开游戏里面的有限状态机(finite state machines,FSM)而单独只谈"状态模式".不过,当我讲到FSM的时候,我发觉我还有必要再介绍一下层次状态机(hierarchical state machine)和下推自动机(pushdown automat

《游戏编程模式》一7.6 进入状态和退出状态的行为

7.6 进入状态和退出状态的行为 状态模式的目标就是将每个状态相关的所有的数据和行为封装到相关类里面.万里长征,我们仅仅迈出去了一步,我们还有更多路要走. 当主角更改状态的时候,我们也会切换它的贴图.现在,这段代码包含在它要切换的状态的上一个状态里面.当她从躲避状态切换到站立状态时,躲避状态将会修改它的图像: HeroineState* DuckingState::handleInput( Heroine& heroine, Input input) { if (input == RELEASE

《游戏编程模式》一导读

前 言 游戏编程模式在五年级的时候,我和我的小伙伴们获准使用一个放置着几台非常破旧的TRS-80s[1]的闲置教室.为了激励我们,一位老师找到了一份印有一些简单BASIC程序的打印文档给我们. 当时,计算机上的音频磁带驱动器是坏掉的,所以每次我们想要运行一些代码的时候,都不得不仔细地从头开始键入代码.这使得我们更喜欢那些只有几行代码的程序: 如果计算机打印足够多的次数,或许它会神奇的变成现实哦[2]. 10 PRINT "BOBBY IS RADICAL!!!" 20 GOTO 10

详解state状态模式及在C++设计模式编程中的使用实例_C 语言

每个人.事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State).最简单的一个生活中的例子就是:地铁入口处,如果你放入正确的地铁票,门就会打开让你通过.在出口处也是验票,如果正确你就可以 ok,否则就不让你通过(如果你动作野蛮,或许会有报警(Alarm),:)). 有限状态自动机(FSM)也是一个典型的状态不同,对输入有不同的响应(状态转移). 通常我们在实现这类系统会使用到很多的 Switch/Case 语句,Case 某种状态,发生什么动作,C