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 }

    输出结果:

  • 相关阅读:
    anime.js 学习笔记
    swiper 报错 ‘ Can't find variable: Dom7’
    团队管理(二)
    团队管理(一)
    针对数值型数据的相关记录
    react+echarts折柱图实现
    侧边广告之心跳动画
    浅谈尾调用和尾递归
    elementUI 日期选择器获取CRON值
    elementUI 日期选择器之禁止年份事件二
  • 原文地址:https://www.cnblogs.com/SmallAndGreat/p/13564964.html
Copyright © 2011-2022 走看看