状态模式其意图是在一个对象的状态发生变化时能够同时改变它的行为。一个生活中比较常见的例子就如你(是指你自己本人)在走时时,整个人全身的动作是双手臂前后慢慢摇摆且双脚也是一步一步慢慢往前移的,即:该走路状态下,你所对应的是走路动作;在跑步时,你的双手双脚动作明显频率、步伐都加快,即:在跑步状态下,你所对应的是跑步动作;........;在睡着时,你的全身都是不动的,即:睡着状态下,你是处于睡觉的动作状态。在实际项目开发中,(该模式)最常见的框架设计便是FSM了。模式的类关系结构图参考如下:
编码结构参考如下:
1 // the header file 2 // ---------------------------------------------------------------- 3 #pragma once 4 5 #include "Framework/Foundation/GFGlobalDefine.h" 6 7 NSGF_BEGIN 8 9 template<typename T> 10 class IGFState; 11 12 /****************************************************************************** 13 * create : (jacc.kim) [8-18-2015] 14 * summary : class IGFStateFSM 15 ******************************************************************************/ 16 template<typename T> 17 class IGFStateFSM 18 { 19 public: 20 typedef T THost; 21 22 public: 23 inline THost* getHost(); 24 25 inline void setHost(THost* pHostObj); 26 27 public: 28 virtual ~IGFStateFSM(); 29 30 protected: 31 IGFStateFSM(); 32 33 private: 34 IGFStateFSM(const IGFStateFSM<THost>&) DELETE_METHOD; 35 IGFStateFSM& operator=(const IGFStateFSM<THost>&) DELETE_METHOD; 36 37 private: 38 THost* m_pHost; 39 40 };//template<typename T> class IGFStateFSM 41 42 /****************************************************************************** 43 * create : (jacc.kim) [8-18-2015] 44 * summary : class IGFState 45 ******************************************************************************/ 46 template<typename T> 47 class IGFState 48 { 49 public: 50 typedef T THost; 51 52 public: 53 inline THost* getHost(); 54 55 inline void setHost(THost* pHostObj); 56 57 virtual bool canTrans(); 58 59 virtual void run(); 60 61 virtual void enter(); 62 63 virtual void exit(); 64 65 public: 66 virtual ~IGFState(); 67 68 protected: 69 IGFState(IGFStateFSM<THost>* pFSM); 70 IGFState(const IGFState<THost>&) DELETE_METHOD; 71 IGFState& operator=(const IGFState<THost>&) DELETE_METHOD; 72 73 IGFStateFSM<THost>* getFSM(); 74 75 private: 76 THost* m_pHost; 77 IGFStateFSM<THost>* m_pFSM; 78 79 };//template<typename T> class IGFState 80 81 NSGF_END 82 83 #include "Framework/Foundation/IGFState.inl" 84 85 // ---------------------------------------------------------------- 86 // the inl file 87 // ---------------------------------------------------------------- 88 #include "Framework/Foundation/GFHeader.h" 89 90 NSGF_BEGIN 91 92 /////////////////////////////////////////////////////////////////////////////// 93 // template<typename T> class IGFStateFSM 94 template<typename T> 95 nsgf::IGFStateFSM<T>::IGFStateFSM() : m_pHost(nullptr) 96 { 97 98 } 99 100 template<typename T> 101 nsgf::IGFStateFSM<T>::~IGFStateFSM() { 102 103 } 104 105 template<typename T> 106 inline typename nsgf::IGFStateFSM<T>::THost* nsgf::IGFStateFSM<T>::getHost() { 107 return m_pHost; 108 } 109 110 template<typename T> 111 inline void nsgf::IGFStateFSM<T>::setHost(typename THost* pHostObj) { 112 m_pHost = pHostObj; 113 } 114 115 /////////////////////////////////////////////////////////////////////////////// 116 // template<typename T> class IGFState 117 template<typename T> 118 nsgf::IGFState<T>::IGFState(IGFStateFSM<THost>* pFSM) : m_pHost(nullptr) 119 , m_pFSM(pFSM) 120 { 121 122 } 123 124 template<typename T> 125 nsgf::IGFState<T>::~IGFState() { 126 127 } 128 129 template<typename T> 130 inline typename nsgf::IGFState<T>::THost* nsgf::IGFState<T>::getHost() { 131 return m_pHost; 132 } 133 134 template<typename T> 135 inline void nsgf::IGFState<T>::setHost(typename THost* pHostObj) { 136 m_pHost = pHostObj; 137 } 138 139 template<typename T> 140 bool nsgf::IGFState<T>::canTrans() { 141 return false; 142 } 143 144 template<typename T> 145 void nsgf::IGFState<T>::run() { 146 // some code here........ 147 } 148 149 template<typename T> 150 void nsgf::IGFState<T>::enter() { 151 // some code here........ 152 } 153 154 template<typename T> 155 void nsgf::IGFState<T>::exit() { 156 // some code here........ 157 } 158 159 template<typename T> 160 IGFStateFSM<T>* nsgf::IGFState<T>::getFSM() { 161 return m_pFSM; 162 } 163 164 NSGF_END
状态模式使得原本是完整体的对象被依据状态切分成多个状态的子模块组合而成,有利也有弊。对于原本就比较复杂,拥有很多状态的对像来说,使用该模式将会使结构更加的清晰,一种状态就对应一个相应的类封装,并且当前某种状态的后续状态也是明确的。特别在对于那些某一时刻,只会存在一个具体状态的对象来说,状态模式可以说是十分完美的。
但也正因为对象被切分成众多的状态集合,也造成了各状态间的交互障碍(因为有时免不了某一状态会依赖于另一状态的某些属性等,毕竟它们都是服务于目标对象),从而在一定程度上破坏了OOP的封装特性。还有更头疼的是对于目标对象来说,如果同一时间要是允许同时存在不止一种状态的话,那就比较悲催。举个例子:游戏中某一角色在遇到敌人时,它可以边躲避敌人的子弹射击,同时可以边向对方射击。这边就至少有两个状态,一是逃跑躲避行为状态;二是向对方射击行为状态。那问题来了,哪个主哪个辅?又或它们并级(别)?再举个例子:某角色被敌方晕住了,同时又被别一个敌人给击飞了(即:被敌人在很敌的时间内,推开很远的距离)。像这边也至少有两种状态。还有更复杂的,多于两种状态同时存在的情况,则情况将是更加复杂的。因此,随着(State模式的)应用越来越广、(遇到的)问题越来越复杂,简单的状态模式设计也逐渐暴露出其弊端。于是后来就有HFMS、BT出现。就个人,还是更推荐BT,感觉这个设计的灵活性会更好些。至于HFMS除了使设计、调试更加复杂外,还是没能完全解决State模式设计的缺陷。