zoukankan      html  css  js  c++  java
  • C++设计模式-State状态模式

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

    UML图如下:


    State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为。
    ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
    Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态。

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

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

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

    可以消除庞大的条件分支语句。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。

    当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。
    另外如果业务需求某项业务有多个状态,通常都是一些枚举常量,状态的变化都是依靠大量的多分支判断语句来实现,此时应该考虑将每一种业务状态定义为一个State的子类。这样这些对象就可以不依赖于其他对象儿独立变化了。

    代码如下:

    State.h

     1 #ifndef _STATE_H_
     2 #define _STATE_H_
     3 
     4 class Context;
     5 class State
     6 {
     7 public:
     8     virtual void Handle(Context* pContext)=0;
     9     ~State();
    10 protected:
    11     State();
    12 private:
    13 };
    14 
    15 class ConcreteStateA : public State
    16 {
    17 public:
    18     ConcreteStateA();
    19     ~ConcreteStateA();
    20     virtual void Handle(Context* pContext);
    21 protected:
    22 private:
    23 };
    24 
    25 class ConcreteStateB : public State
    26 {
    27 public:
    28     ConcreteStateB();
    29     ~ConcreteStateB();
    30     virtual void Handle(Context* pContext);
    31 protected:
    32 private:
    33 };
    34 
    35 class ConcreteStateC : public State
    36 {
    37 public:
    38     ConcreteStateC();
    39     ~ConcreteStateC();
    40     virtual void Handle(Context* pContext);
    41 protected:
    42 private:
    43 };
    44 
    45 class Context
    46 {
    47 public:
    48     Context(State* pState);
    49     ~Context();
    50     void Request();
    51     void ChangeState(State* pState);
    52 protected:
    53 private:
    54     State* _state;
    55 };
    56 
    57 #endif

    State.cpp

     1 #include "State.h"
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 State::State()
     7 {}
     8 
     9 State::~State()
    10 {}
    11 
    12 ConcreteStateA::ConcreteStateA()
    13 {}
    14 
    15 ConcreteStateA::~ConcreteStateA()
    16 {}
    17 
    18 //执行该状态的行为并改变状态
    19 void ConcreteStateA::Handle(Context* pContext)
    20 {
    21     cout << "ConcreteStateA" << endl;
    22     pContext->ChangeState(new ConcreteStateB());
    23 }
    24 
    25 ConcreteStateB::ConcreteStateB()
    26 {}
    27 
    28 ConcreteStateB::~ConcreteStateB()
    29 {}
    30 
    31 //执行该状态的行为并改变状态
    32 void ConcreteStateB::Handle(Context* pContext)
    33 {
    34     cout << "ConcreteStateB" << endl;
    35     pContext->ChangeState(new ConcreteStateC());
    36 }
    37 
    38 ConcreteStateC::ConcreteStateC()
    39 {}
    40 
    41 ConcreteStateC::~ConcreteStateC()
    42 {}
    43 
    44 //执行该状态的行为并改变状态
    45 void ConcreteStateC::Handle(Context* pContext)
    46 {
    47     cout << "ConcreteStateC" << endl;
    48     pContext->ChangeState(new ConcreteStateA());
    49 }
    50 
    51 //定义_state的初始状态
    52 Context::Context(State* pState)
    53 {
    54     this->_state = pState;
    55 }
    56 
    57 Context::~Context()
    58 {}
    59 
    60 //对请求做处理,并设置下一状态
    61 void Context::Request()
    62 {
    63     if(NULL != this->_state)
    64     {
    65         this->_state->Handle(this);
    66     }
    67 }
    68 
    69 //改变状态
    70 void Context::ChangeState(State* pState)
    71 {
    72     this->_state = pState;
    73 }

    main.cpp

     1 #include "State.h"
     2 
     3 int main()
     4 {
     5     State* pState = new ConcreteStateA();
     6     Context* pContext = new Context(pState);
     7     pContext->Request();
     8     pContext->Request();
     9     pContext->Request();
    10     pContext->Request();
    11     pContext->Request();
    12     return 0;
    13 }
  • 相关阅读:
    安卓任意两个或多个Fragment之间的交互与刷新界面
    内存溢出和内存泄漏
    求直方图围成的最大矩形面积
    判断一个字符串是否是由另2个字符串交错组成的
    矩阵的旋转
    求滑动窗口的最大值
    面向过程和面向对象的区别
    关于丑数
    求连续子数组的最大和
    多数投票算法(Majority Vote Algorithm)
  • 原文地址:https://www.cnblogs.com/jiese/p/3182342.html
Copyright © 2011-2022 走看看