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