简述:
状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式包括:抽象状态类、具体状态类、具体状态维护类
抽象状态类:定义一个接口以封装与具体状态维护类的一个特定状态相关的行为。
具体状态类:每一个子类实现一个与具体状态维护类的一个状态相关的行为。
状态模式代码:
1 #include <iostream> 2 using namespace std; 3 4 class CContext; 5 // 抽象状态类 6 class CState 7 { 8 public: 9 string m_szName; 10 CState() : m_szName("") {} 11 virtual void Handle(CContext* pContext) = 0; 12 }; 13 14 // 具体状态维护类 15 class CContext 16 { 17 private: 18 CState* m_pState; 19 20 public: 21 CContext(CState* pState) { m_pState = pState; } 22 23 void SetState(CState* pState) 24 { 25 m_pState = pState; 26 cout << "当前的状态:" << m_pState->m_szName << endl; 27 } 28 CState* GetState() { return m_pState; } 29 30 void Request(){ m_pState->Handle(this); } 31 }; 32 33 // 具体状态类 34 class CConcreteStateA : public CState 35 { 36 public: 37 CState* m_pConcreteStateB; 38 39 public: 40 CConcreteStateA() 41 { 42 m_szName = "A"; 43 m_pConcreteStateB = NULL; 44 } 45 46 virtual void Handle(CContext* pContext) 47 { 48 pContext->SetState(m_pConcreteStateB); 49 } 50 }; 51 52 // 具体状态类 53 class CConcreteStateB : public CState 54 { 55 public: 56 CState* m_pConcreteStateA; 57 58 public: 59 CConcreteStateB() 60 { 61 m_pConcreteStateA = NULL; 62 m_szName = "B"; 63 } 64 65 virtual void Handle(CContext* pContext) 66 { 67 pContext->SetState(m_pConcreteStateA); 68 } 69 }; 70 71 int main() 72 { 73 CConcreteStateA ConcreteStateA; 74 CConcreteStateB ConcreteStateB; 75 ConcreteStateA.m_pConcreteStateB = &ConcreteStateB; 76 ConcreteStateB.m_pConcreteStateA = &ConcreteStateA; 77 CContext Context(&ConcreteStateA); 78 Context.Request(); 79 Context.Request(); 80 Context.Request(); 81 Context.Request(); 82 system("pause"); 83 return 0; 84 }
运行结果:
例:不同时间点工作状态
代码如下:
1 #include <iostream> 2 using namespace std; 3 4 class CWork; 5 // 抽象状态类 6 class CState 7 { 8 public: 9 virtual void WriteProgram(CWork* pWork) = 0; 10 }; 11 12 // 工作类(具体状态维护类) 13 class CWork 14 { 15 private: 16 CState* m_pCurrentState; 17 int m_nHour; 18 bool m_bFinished; 19 20 public: 21 CWork(CState* pState) : m_nHour(0), m_bFinished(false) 22 { 23 m_pCurrentState = pState; 24 } 25 26 void SetTime(int nHour) 27 { 28 m_nHour = nHour; 29 } 30 31 int GetTime() 32 { 33 return m_nHour; 34 } 35 36 void SetState(CState* pState) 37 { 38 m_pCurrentState = pState; 39 } 40 41 void SetTaskFinished(bool bFinished) 42 { 43 m_bFinished = bFinished; 44 } 45 46 bool GetTaskFinished() 47 { 48 return m_bFinished; 49 } 50 51 void WriteProgram() 52 { 53 m_pCurrentState->WriteProgram(this); 54 } 55 }; 56 57 // 具体状态类 58 class CForenoonState : public CState 59 { 60 public: 61 CState* m_pNoonState; 62 public: 63 virtual void WriteProgram(CWork* pWork) 64 { 65 if (pWork->GetTime() < 12) 66 cout << "当前时间[" << pWork->GetTime() << "]点,上午工作,精神百倍。" << endl; 67 else 68 { 69 pWork->SetState(m_pNoonState); 70 pWork->WriteProgram(); 71 } 72 } 73 }; 74 75 // 具体状态类 76 class CNoonState : public CState 77 { 78 public: 79 CState* m_pAfterNoonState; 80 public: 81 virtual void WriteProgram(CWork* pWork) 82 { 83 if (pWork->GetTime() < 13) 84 cout << "当前时间[" << pWork->GetTime() << "]点,午饭,犯困,午休。" << endl; 85 else 86 { 87 pWork->SetState(m_pAfterNoonState); 88 pWork->WriteProgram(); 89 } 90 } 91 }; 92 93 // 具体状态类 94 class CAfterNoonState : public CState 95 { 96 public: 97 CState* m_pEveningState; 98 public: 99 virtual void WriteProgram(CWork* pWork) 100 { 101 if (pWork->GetTime() < 17) 102 cout << "当前时间[" << pWork->GetTime() << "]点,下午状态还不错,继续努力。" << endl; 103 else 104 { 105 pWork->SetState(m_pEveningState); 106 pWork->WriteProgram(); 107 } 108 } 109 }; 110 111 // 具体状态类 112 class CEveningState : public CState 113 { 114 public: 115 CState* m_pSleepingState; 116 CState* m_pRestState; 117 public: 118 virtual void WriteProgram(CWork* pWork) 119 { 120 if (pWork->GetTaskFinished()) 121 { 122 pWork->SetState(m_pRestState); 123 pWork->WriteProgram(); 124 } 125 else 126 { 127 if (pWork->GetTime() < 21) 128 cout << "当前时间[" << pWork->GetTime() << "]点,加班哦,疲惫之极。" << endl; 129 else 130 { 131 pWork->SetState(m_pSleepingState); 132 pWork->WriteProgram(); 133 } 134 } 135 } 136 }; 137 138 // 具体状态类 139 class CSleepingState : public CState 140 { 141 public: 142 virtual void WriteProgram(CWork* pWork) 143 { 144 cout << "当前时间[" << pWork->GetTime() << "]点,不行了,睡着了。" << endl; 145 } 146 }; 147 148 // 具体状态类 149 class CRestState : public CState 150 { 151 public: 152 virtual void WriteProgram(CWork* pWork) 153 { 154 cout << "当前时间[" << pWork->GetTime() << "]点,下班回家了。" << endl; 155 } 156 }; 157 158 int main() 159 { 160 // C++的相互包含很微妙,不能像C#使用那么随意,可以用基类的指针实现,所以代码看起来比较冗余,也是我比较懒,没有对状态转换对象进行深入的处理。 161 // 同时我为了避免使用堆区变量,都用了栈区变量传指针的方式。 162 CForenoonState ForenoonState; 163 CNoonState NoonState; 164 CAfterNoonState AfterNoonState; 165 CEveningState EveningState; 166 CSleepingState SleepingState; 167 CRestState RestState; 168 ForenoonState.m_pNoonState = &NoonState; 169 NoonState.m_pAfterNoonState = &AfterNoonState; 170 AfterNoonState.m_pEveningState = &EveningState; 171 EveningState.m_pSleepingState = &SleepingState; 172 EveningState.m_pRestState = &RestState; 173 174 CWork emergencyProjects(&ForenoonState); 175 emergencyProjects.SetTime(9); 176 emergencyProjects.WriteProgram(); 177 emergencyProjects.SetTime(10); 178 emergencyProjects.WriteProgram(); 179 emergencyProjects.SetTime(12); 180 emergencyProjects.WriteProgram(); 181 emergencyProjects.SetTime(13); 182 emergencyProjects.WriteProgram(); 183 emergencyProjects.SetTime(14); 184 emergencyProjects.WriteProgram(); 185 emergencyProjects.SetTime(17); 186 //emergencyProjects.SetTaskFinished(true); 187 emergencyProjects.SetTaskFinished(false); 188 emergencyProjects.WriteProgram(); 189 emergencyProjects.SetTime(19); 190 emergencyProjects.WriteProgram(); 191 emergencyProjects.SetTime(22); 192 emergencyProjects.WriteProgram(); 193 system("pause"); 194 return 0; 195 }
输出结果: