状态设计模式笔记

状态模式(State),当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类【DP】

 

状态模式主要解决的是,当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。

 

当然如果这个状态判断很简单,那就没有必要用‘状态模式’了。

 

 

我的实现源代码:

state.h

 1 #ifndef STATE_H
 2 #define STATE_H
 3 
 4 class Context;
 5 //my code
 6 class State
 7 {
 8 public:
 9     virtual void Handle(Context *pContext) = 0;
10 };
11 
12 class Context
13 {
14 public:
15     Context(State *pState);
16     ~Context();
17     void Request();
18     void SetState(State *pState);
19 
20 private:
21     State *m_State;
22 };
23 
24 class ConcreteA : public State
25 {
26 public:
27     virtual void Handle(Context *pContext);
28 };
29 
30 class ConcreteB : public State
31 {
32 public:
33     virtual void Handle(Context *pContext);
34 };
35 
36 #endif // STATE_H

state.cpp:

 1 #include "state.h"
 2 #include <iostream>
 3 
 4 using namespace std;
 5 
 6 Context::Context(State *pState)
 7 {
 8     this->m_State = pState;
 9 }
10 
11 Context::~Context()
12 {
13 
14 }
15 
16 void Context::SetState(State *pState)
17 {
18     if(pState != NULL)
19         this->m_State = pState;
20 }
21 
22 void Context::Request()
23 {
24     this->m_State->Handle(this);
25 }
26 
27 void ConcreteA::Handle(Context *pContext)
28 {
29     cout<<"this is concrete A"<<endl;
30     pContext->SetState(new ConcreteB());
31 }
32 
33 void ConcreteB::Handle(Context *pContext)
34 {
35     cout<<"this is concrete B"<<endl;
36     pContext->SetState(new ConcreteA());
37 }

main.cpp

#include <iostream>
#include "state.h"

using namespace std;

int main()
{
    State *pState = new ConcreteA();
    Context *c = new Context(pState);

    c->Request();
    c->Request();
    c->Request();
    c->Request();
    return 0;
}

 

状态模式好处与用处

“状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来【DP】。”

“将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换【DP】。”

 

主要的目的是:消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖,好比把整个版面改成一个又一个的活字,此时就容易维护和扩展了。

 

当一个对象的行为取决与它的状态,并且他必须在运行时刻根据状态改变它的行为时,就可以考虑状态模式了。

 

工作状态-状态模式版(c++)

workstate.h

 1 #ifndef WORKSTATE_H
 2 #define WORKSTATE_H
 3 
 4 class Work;
 5 
 6 class WorkState
 7 {
 8 public:
 9     virtual void WriteProgram(Work *pWork) = 0;
10     WorkState();
11 };
12 
13 class Work
14 {
15 public:
16     Work(WorkState *pWorkState);
17     void ChangeWorkState(WorkState *pWorkState);
18     int GetWorkHour();
19     void ChangeWorkHour(int hour);
20     void ChangeWorkFinishFlag(bool flag);
21     bool GetWorkFinishFlag();
22     void Writing();
23 
24 private:
25     WorkState *m_WorkState;
26     int m_Hour;
27     bool m_Finishflag;
28 };
29 
30 class WorkMorning : public WorkState
31 {
32 public:
33     virtual void WriteProgram(Work *pWork);
34 };
35 
36 class WorkNoon : public WorkState
37 {
38 public:
39     virtual void WriteProgram(Work *pWork);
40 };
41 
42 class WorkAfternoon : public WorkState
43 {
44 public:
45     virtual void WriteProgram(Work *pWork);
46 };
47 
48 class WorkNight : public WorkState
49 {
50 public:
51     virtual void WriteProgram(Work *pWork);
52 };
53 
54 class WorkOff : public WorkState
55 {
56 public:
57     virtual void WriteProgram(Work *pWork);
58 };
59 
60 class WorkSleep : public WorkState
61 {
62 public:
63     virtual void WriteProgram(Work *pWork);
64 };
65 
66 #endif // WORKSTATE_H
WorkState

workstate.cpp

  1 #include "workstate.h"
  2 #include <iostream>
  3 
  4 using namespace std;
  5 
  6 WorkState::WorkState()
  7 {
  8 
  9 }
 10 
 11 Work::Work(WorkState *pWorkState)
 12 {
 13     this->m_WorkState = pWorkState;
 14     this->m_Hour = 0;
 15     this->m_Finishflag = false;
 16 }
 17 
 18 void Work::ChangeWorkState(WorkState *pWorkState)
 19 {
 20     this->m_WorkState = pWorkState;
 21 }
 22 
 23 int Work::GetWorkHour()
 24 {
 25     return m_Hour;
 26 }
 27 
 28 void Work::ChangeWorkHour(int hour)
 29 {
 30     this->m_Hour = hour;
 31 }
 32 
 33 void Work::ChangeWorkFinishFlag(bool flag)
 34 {
 35     this->m_Finishflag = flag;
 36 }
 37 
 38 bool Work::GetWorkFinishFlag()
 39 {
 40     return m_Finishflag;
 41 }
 42 
 43 void Work::Writing()
 44 {
 45     this->m_WorkState->WriteProgram(this);
 46 }
 47 
 48 void WorkMorning::WriteProgram(Work *pWork)
 49 {
 50     if(pWork->GetWorkHour() < 12)
 51         cout<<"WorkMorning: Work very good."<<endl;
 52     else{
 53 //        cout<<"WorkMorning: change to Noon"<<endl;
 54         pWork->ChangeWorkState(new WorkNoon());
 55         pWork->Writing();                       //切换后运行
 56     }
 57 }
 58 
 59 void WorkNoon::WriteProgram(Work *pWork)
 60 {
 61     if(pWork->GetWorkHour() < 13)
 62         cout<<"WorkNoon: hungry, lunch: sleeping"<<endl;
 63     else {
 64         pWork->ChangeWorkState(new WorkAfternoon());
 65         pWork->Writing();
 66     }
 67 }
 68 
 69 void WorkAfternoon::WriteProgram(Work *pWork)
 70 {
 71     if(pWork->GetWorkHour() < 17)
 72             cout<<"WorkAfternoon: Work very good"<<endl;
 73     else {
 74         pWork->ChangeWorkState(new WorkNight());
 75         pWork->Writing();
 76     }
 77 }
 78 
 79 void WorkNight::WriteProgram(Work *pWork)
 80 {
 81     if(pWork->GetWorkFinishFlag()) {
 82         pWork->ChangeWorkState(new WorkOff());
 83         pWork->Writing();
 84     }
 85     else {
 86         if(pWork->GetWorkHour() < 21)
 87             cout<<"WorkNight: Work very tired"<<endl;
 88         else {
 89             pWork->ChangeWorkState(new WorkSleep());
 90             pWork->Writing();
 91         }
 92     }
 93 }
 94 
 95 void WorkOff::WriteProgram(Work *pWork)
 96 {
 97     cout<<"WorkOff: happy"<<endl;
 98 }
 99 
100 void WorkSleep::WriteProgram(Work *pWork)
101 {
102     cout<<"WorkSleep: Can't Work"<<endl;
103 }
WorkState.cpp

main.cpp

 1 #include <iostream>
 2 #include "workstate.h"
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     WorkState *pState = new WorkMorning();
 9     Work *pWork = new Work(pState);
10 
11     pWork->ChangeWorkHour(9);
12     pWork->Writing();
13     pWork->ChangeWorkHour(10);
14     pWork->Writing();
15     pWork->ChangeWorkHour(12);
16     pWork->Writing();
17     pWork->ChangeWorkHour(13);
18     pWork->Writing();
19     pWork->ChangeWorkHour(14);
20     pWork->Writing();
21     pWork->ChangeWorkHour(17);
22 
23     pWork->ChangeWorkFinishFlag(false);
24 //    pWork->ChangeWorkFinishFlag(true);
25     pWork->Writing();
26 
27     pWork->ChangeWorkHour(19);
28     pWork->Writing();
29     pWork->ChangeWorkHour(22);
30     pWork->Writing();
31 
32     return 0;
33 }
main.cpp

 

posted @ 2018-01-26 16:01  习惯就好233  阅读(132)  评论(0编辑  收藏  举报