状态模式State

状态模式:

    当一个对象的行为取决于它的状态,并且在输入事件或者随着时间的推移会改变对象的状态。那么就把行为封装到状态中,为每一个状态设计一个类。

   例子:

        根据玩家的输入来控制主角的行为--《游戏编程模式》

        糖果机的实现,根据顾客的操作来控制糖果机的行为--《HeadFirst设计模式》

        均可以画一个状态转移图


状态模式类图:


concreteStateA 与 ConcreteStateB 之间的状态转化对 Context 是透明的,Context只知道初始状态和当前状态,对如何转化状态并不知道。


状态模式设计流程

        1.定义状态接口,每一个与状态相关的行为都定义为虚函数。【State。

        2.为每一个具体状态定义一个类继承自状态接口,并实现具体的行为。【ConCreteState

        3.把对象的行为委托给当前状态的行为。【Context的request委托给state的handle()

                玩家的handleInput 调用 curState的handleInput

                糖果机的InsertQuarter 调用 curState的InsertQuarter


状态对象的生成方式

1.静态状态

        限制:状态中不能含有自己的数据成员。

        优点:多个context对象可以共享状态。

                   在state.handle 需要把context作为参数传入 state.handle(context* )

2.实例化状态

        1)由context实例化,拥有所有的状态实例。当前状态是这些实例之一。(每个状态可以拥有一个context指针数据成员,handle的时候就不需要传入context指针了)

        2)由具体状态类 动态创建新状态,由context销毁旧状态。



状态模式的缺点

1) 状态模式的使用必然会增加系统类和对象的个数。

2) 状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱


先判断输入,再判断当前所处的状态,根据状态做出行为。

vs

先判断当前状态,再判断输入的是什么,再根据输入做出行为。

vs

把状态设计成类,把根据输入做出行为设计成类的函数。


与策略模式比较

同:类图一致。均有主对象的行为委托给附属对象

异:目标不同:

          策略模式的目标是将主类与它的部分行为进行解耦。  策略模式中主动制定context所要组合的【策略对象】。

          状态模式的目标是通过改变主对象代理的对象来改变主对象的行为。状态模式中context对于【状态对象】的改变了解不多,而是由【状态对象】去控制状态转换。  


策略模式 --- 除了继承之外的一种弹性替代方案。

状态模式 --- 不用在context中防止许多条件判断的替代方案。


参考资料

《headfirst设计模式》

《游戏编程模式》

猜你喜欢

转载自blog.csdn.net/u012138730/article/details/79958575