zoukankan      html  css  js  c++  java
  • 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 }

    输出结果:

  • 相关阅读:
    LeetCode "Palindrome Partition II"
    LeetCode "Longest Substring Without Repeating Characters"
    LeetCode "Wildcard Matching"
    LeetCode "Best Time to Buy and Sell Stock II"
    LeetCodeEPI "Best Time to Buy and Sell Stock"
    LeetCode "Substring with Concatenation of All Words"
    LeetCode "Word Break II"
    LeetCode "Word Break"
    Some thoughts..
    LeetCode "Longest Valid Parentheses"
  • 原文地址:https://www.cnblogs.com/SmallAndGreat/p/13564964.html
Copyright © 2011-2022 走看看