012 --- 第16章 状态模式

简述:

  状态模式:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

  状态模式包括:抽象状态类、具体状态类、具体状态维护类

    抽象状态类:定义一个接口以封装与具体状态维护类的一个特定状态相关的行为。

    具体状态类:每一个子类实现一个与具体状态维护类的一个状态相关的行为。

状态模式代码:

 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 }

输出结果:

原文地址:https://www.cnblogs.com/SmallAndGreat/p/13564964.html