状态模式其意图是在一个对象的状态发生变化时能够同时改变它的行为。一个生活中比较常见的例子就如你(是指你自己本人)在走时时,整个人全身的动作是双手臂前后慢慢摇摆且双脚也是一步一步慢慢往前移的,即:该走路状态下,你所对应的是走路动作;在跑步时,你的双手双脚动作明显频率、步伐都加快,即:在跑步状态下,你所对应的是跑步动作;........;在睡着时,你的全身都是不动的,即:睡着状态下,你是处于睡觉的动作状态。在实际项目开发中,(该模式)最常见的框架设计便是FSM了。模式的类关系结构图参考如下:

编码结构参考如下:

 // the header file
// ----------------------------------------------------------------
#pragma once #include "Framework/Foundation/GFGlobalDefine.h" NSGF_BEGIN template<typename T>
class IGFState; /******************************************************************************
* create : (jacc.kim) [8-18-2015]
* summary : class IGFStateFSM
******************************************************************************/
template<typename T>
class IGFStateFSM
{
public:
typedef T THost; public:
inline THost* getHost(); inline void setHost(THost* pHostObj); public:
virtual ~IGFStateFSM(); protected:
IGFStateFSM(); private:
IGFStateFSM(const IGFStateFSM<THost>&) DELETE_METHOD;
IGFStateFSM& operator=(const IGFStateFSM<THost>&) DELETE_METHOD; private:
THost* m_pHost; };//template<typename T> class IGFStateFSM /******************************************************************************
* create : (jacc.kim) [8-18-2015]
* summary : class IGFState
******************************************************************************/
template<typename T>
class IGFState
{
public:
typedef T THost; public:
inline THost* getHost(); inline void setHost(THost* pHostObj); virtual bool canTrans(); virtual void run(); virtual void enter(); virtual void exit(); public:
virtual ~IGFState(); protected:
IGFState(IGFStateFSM<THost>* pFSM);
IGFState(const IGFState<THost>&) DELETE_METHOD;
IGFState& operator=(const IGFState<THost>&) DELETE_METHOD; IGFStateFSM<THost>* getFSM(); private:
THost* m_pHost;
IGFStateFSM<THost>* m_pFSM; };//template<typename T> class IGFState NSGF_END #include "Framework/Foundation/IGFState.inl" // ----------------------------------------------------------------
// the inl file
// ----------------------------------------------------------------
#include "Framework/Foundation/GFHeader.h" NSGF_BEGIN ///////////////////////////////////////////////////////////////////////////////
// template<typename T> class IGFStateFSM
template<typename T>
nsgf::IGFStateFSM<T>::IGFStateFSM() : m_pHost(nullptr)
{ } template<typename T>
nsgf::IGFStateFSM<T>::~IGFStateFSM() { } template<typename T>
inline typename nsgf::IGFStateFSM<T>::THost* nsgf::IGFStateFSM<T>::getHost() {
return m_pHost;
} template<typename T>
inline void nsgf::IGFStateFSM<T>::setHost(typename THost* pHostObj) {
m_pHost = pHostObj;
} ///////////////////////////////////////////////////////////////////////////////
// template<typename T> class IGFState
template<typename T>
nsgf::IGFState<T>::IGFState(IGFStateFSM<THost>* pFSM) : m_pHost(nullptr)
, m_pFSM(pFSM)
{ } template<typename T>
nsgf::IGFState<T>::~IGFState() { } template<typename T>
inline typename nsgf::IGFState<T>::THost* nsgf::IGFState<T>::getHost() {
return m_pHost;
} template<typename T>
inline void nsgf::IGFState<T>::setHost(typename THost* pHostObj) {
m_pHost = pHostObj;
} template<typename T>
bool nsgf::IGFState<T>::canTrans() {
return false;
} template<typename T>
void nsgf::IGFState<T>::run() {
// some code here........
} template<typename T>
void nsgf::IGFState<T>::enter() {
// some code here........
} template<typename T>
void nsgf::IGFState<T>::exit() {
// some code here........
} template<typename T>
IGFStateFSM<T>* nsgf::IGFState<T>::getFSM() {
return m_pFSM;
} NSGF_END

状态模式编码结构参考

状态模式使得原本是完整体的对象被依据状态切分成多个状态的子模块组合而成,有利也有弊。对于原本就比较复杂,拥有很多状态的对像来说,使用该模式将会使结构更加的清晰,一种状态就对应一个相应的类封装,并且当前某种状态的后续状态也是明确的。特别在对于那些某一时刻,只会存在一个具体状态的对象来说,状态模式可以说是十分完美的。

但也正因为对象被切分成众多的状态集合,也造成了各状态间的交互障碍(因为有时免不了某一状态会依赖于另一状态的某些属性等,毕竟它们都是服务于目标对象),从而在一定程度上破坏了OOP的封装特性。还有更头疼的是对于目标对象来说,如果同一时间要是允许同时存在不止一种状态的话,那就比较悲催。举个例子:游戏中某一角色在遇到敌人时,它可以边躲避敌人的子弹射击,同时可以边向对方射击。这边就至少有两个状态,一是逃跑躲避行为状态;二是向对方射击行为状态。那问题来了,哪个主哪个辅?又或它们并级(别)?再举个例子:某角色被敌方晕住了,同时又被别一个敌人给击飞了(即:被敌人在很敌的时间内,推开很远的距离)。像这边也至少有两种状态。还有更复杂的,多于两种状态同时存在的情况,则情况将是更加复杂的。因此,随着(State模式的)应用越来越广、(遇到的)问题越来越复杂,简单的状态模式设计也逐渐暴露出其弊端。于是后来就有HFMS、BT出现。就个人,还是更推荐BT,感觉这个设计的灵活性会更好些。至于HFMS除了使设计、调试更加复杂外,还是没能完全解决State模式设计的缺陷。

【行为型】State模式的更多相关文章

  1. Java 实现状态(State)模式

    /** * @author stone */ public class WindowState { private String stateValue; public WindowState(Stri ...

  2. 敏捷软件开发(1)--- STATE 模式

    如果状态在运行过程中,不停的切换和改变,我们怎么办? 状态的迁移是我们生活和工程中非常普遍的一个概念.于是在数学上有一种理论来分析和解决这个问题. 有限状态机理论是一个非常成熟的理论,所有动作和流程的 ...

  3. State模式的经典应用场景:订单处理(c#实现)

    State模式在对象内部状态发生变化的时候,改变自身的行为,这通常是通过切换内部状态对象实现的,对象将自身在各个状态的行为推给了状态对象,从而解开了行为与对象的依赖. 场景描述 在经典的订单处理场景中 ...

  4. 无聊之作,RPGdemo制作(一)角色state模式

    今天周末,在家无事可做,不知道为什么,突发奇想,想写一个RPG游戏的demo玩玩.所以就记录一下. 第一步要做的是,为以后的角色类写一个state模式的类,考虑到可能以后会用到,所以用模版来实现, / ...

  5. State模式

    地铁十字转门 状态迁移表格. 起始状态 触发迁移的事件 终止状态  要执行的动作. Locked   Coin               UnLocked UnLock UnLocked Pass  ...

  6. Behavioral模式State模式

    1.意向 同意一个目标,然后改变其内部状态,改变它的行为. 对象似乎改变它的类别. 2.别名 状态对象(Objects for States) 3.动机 考虑一个表示网络连接的类TCPConnecti ...

  7. State 模式

    State模式中我们将状态逻辑和动作实现进行分离.允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类:在一个状态即将结束的时候启用下一个状态. /////////state.h// ...

  8. state模式理解

    state模式应用场景 条件判断很多的情况 比如有很多if else语句:switch case语句等等. 如果以后业务越来越复杂,条件判断有100多个,每种条件的处理逻辑很复杂,不止一个业务逻辑会重 ...

  9. State模式学习笔记

    选用了一个假设需要用户验证的例子进行State模式学习,这个例子并不恰当.无所谓了,只要能学习到其中的内容即可. 适用性: 1,一个对象的行为取决于他的状态,并且它必须在运行时刻依据状态改变他的行为. ...

随机推荐

  1. Final对象

    常量指不能改变的量. 在Java中用final标志,声明方式和变量类似: final double PI = 3.1415927; 虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量. ...

  2. flex与C# Socket通信

    原文地址:http://blog.csdn.net/LX10752p/archive/2011/04/27/6366526.aspx Socket 通信没什么好说,一个服务端,多个客户端,很容易搭建环 ...

  3. 第k大值01背包问题

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 /* 第一行输入t 代表t组测试数据 第二行 输入物品个数 背包容量 要求的第k大值 物品的价值 物品的重 ...

  4. [Locked] Best Meeting Point

    Best Meeting Point A group of two or more people wants to meet and minimize the total travel distanc ...

  5. Postman interceptor

    安装 下载地址: Postman Interceptor Chrome插件下载 1. 下载的是一个crx文件. 2. 在谷歌中打开: chrome://extensions/ 3. 拖动cfx文件到 ...

  6. 传智播客课程——Lucene搜索引擎

    Lucene不是一个现成的程序,类似文件搜索程序或web网络爬行器或是一个网站的搜索引擎.Lucene是一个软件库,一个开发工具包,而不是一个具有完整特征的搜索应用程序.它本身只关注文本的索引和搜索. ...

  7. C#修饰符

    声明类的顺序: 访问修饰符+类修饰符 +class+类名 { 成员修饰符+ 成员类型 +成员名称; } C#中类及类型成员权限访问修饰符有以下四类:public,private,protected,i ...

  8. 树莓派_Linux串口编程_实现自发自收

    串口是计算机上一种很通用设备通信的协议,经常使用PC机上包括的是RS232规格的串口,具有连接线少,通讯简单,得到广泛的使用. Linux对全部设备的訪问是通过设备文件来进行的,串口也是这样,为了訪问 ...

  9. javascript中错误使用var造成undefined

    在javascript中依据变量作用的范围不同分为局部变量和全局变量,直接定义的变量是全局变量,全局变量能够被全部的脚本訪问:在函数中定义的变量是局部变量,局部变量仅仅在函数内有效. 假设全局变量和局 ...

  10. [Angualr 2] Watch for changes

    You can watch for form / control changes by using .valueChanges.observe({...}): this.sku.valueChange ...