• State Pattern


    1.每个人、事物在不同的状态下会有不同表现(动作),而一个状态又会在不同的表现下转移到下一个不同的状态(State).State Pattern 将每一个分支都封装到独立的类中,将状态逻辑和动作实现进行分离。提高了系统的扩展性和可维护性。

    2.State Pattern结构图

    3.实现:如果代码看的不懂,可以运行main()代码单步跟踪就明白了。

     1 #ifndef _STATE_H_ 
     2 #define _STATE_H_
     3 
     4 class Context; //前置声明
     5 class State 
     6 {
     7 public: 
     8     State();
     9     virtual ~State();
    10     virtual void OperationInterface(Context* ) = 0;
    11     virtual void OperationChangeState(Context*) = 0;
    12 protected: 
    13     bool ChangeState(Context* con,State* st);
    14 private: 
    15     //bool ChangeState(Context* con,State* st);
    16 };
    17 
    18 class ConcreteStateA:public State 
    19 {
    20 public: 
    21     ConcreteStateA();
    22     virtual ~ConcreteStateA();
    23     virtual void OperationInterface(Context* );
    24     virtual void OperationChangeState(Context*);
    25 protected:
    26 private:
    27 };
    28 
    29 class ConcreteStateB:public State 
    30 { 
    31 public:
    32     ConcreteStateB();
    33     virtual ~ConcreteStateB();
    34     virtual void OperationInterface(Context* );
    35     virtual void OperationChangeState(Context*);
    36 protected:
    37 private:
    38 }; 
    39 
    40 #endif
    State.h
     1 #include "State.h" 
     2 #include "Context.h" 
     3 #include <iostream> 
     4 using namespace std;
     5 
     6 State::State() 
     7 {
     8 
     9 }
    10 State::~State() 
    11 {
    12 
    13 }
    14 void State::OperationInterface (Context* con) 
    15 { 
    16     cout<<"State::.."<<endl;
    17 }
    18 bool State::ChangeState(Context* con,State* st) 
    19 { 
    20     con->ChangeState(st);
    21     return true;
    22 }
    23 void State::OperationChangeState(Context* con)
    24 {
    25 
    26 }
    27 /// 
    28 ConcreteStateA::ConcreteStateA() 
    29 {
    30 
    31 }
    32 ConcreteStateA::~ConcreteStateA() 
    33 {
    34 
    35 }
    36 void ConcreteStateA::OperationInterface (Context* con) 
    37 { 
    38     cout<<"ConcreteStateA::OperationInterface ......"<<endl;
    39 }
    40 void ConcreteStateA::OperationChangeState(Context* con) 
    41 {
    42     OperationInterface(con);
    43     this->ChangeState(con,new ConcreteStateB()); 
    44 }
    45 ConcreteStateB::ConcreteStateB() 
    46 {
    47 
    48 }
    49 ConcreteStateB::~ConcreteStateB()
    50 {
    51 
    52 }
    53 void ConcreteStateB::OperationInterface (Context* con) 
    54 { 
    55     cout<<"ConcreteStateB::OperationInterface......"<<endl; 
    56 }
    57 void ConcreteStateB::OperationChangeState (Context* con) 
    58 {
    59     OperationInterface(con);
    60     this->ChangeState(con,new ConcreteStateA()); 
    61 }
    State.cpp
     1 #ifndef _CONTEXT_H_ 
     2 #define _CONTEXT_H_
     3 
     4 class State; /** * **/ 
     5 class Context 
     6 { 
     7 public: 
     8     Context();
     9     Context(State* state);
    10     ~Context();
    11     void OprationInterface();
    12     void OperationChangState();
    13 protected:
    14 private: 
    15     friend class State;
    16     bool ChangeState(State* state);
    17 private: 
    18     State* _state;
    19 };
    20 
    21 #endif
    Context.h
     1 #include "Context.h" 
     2 #include "State.h"
     3 
     4 Context::Context() 
     5 {
     6 
     7 }
     8 Context::Context(State* state) 
     9 {
    10     this->_state = state; 
    11 }
    12 Context::~Context() 
    13 { 
    14     delete _state; 
    15 }
    16 void Context::OprationInterface() 
    17 { 
    18     _state->OperationInterface(this); 
    19 }
    20 bool Context::ChangeState(State* state) 
    21 { ///_state->ChangeState(this,state); 
    22 
    23     this->_state = state;
    24     return true; 
    25 }
    26 void Context::OperationChangState() 
    27 { 
    28     _state->OperationChangeState(this);
    29 }
    Context.cpp
     1 #include "Context.h" 
     2 #include "State.h"
     3 #include <iostream> 
     4 using namespace std;
     5 
     6 int main(int argc,char* argv[]) 
     7 { 
     8     State* st = new ConcreteStateA();
     9     Context* con = new Context(st);
    10     con->OperationChangState();
    11     con->OperationChangState();
    12     con->OperationChangState();
    13     if (con != NULL) delete con;
    14     if (st != NULL) st = NULL;
    15     return 0;
    16 }
    main.cpp

    State模式在实现中的两个关键点:

    (1)将State声明为Context的友元类(friend class),其作用是让State模式访问Context的protected接口ChangeSate()

    (2)State及其子类中的操作都将Context*传入作为参数,其主要目的是State类可以通过这个指针调用Context中的方法(在本示例代码中没有体现)。这也是State模式和Strategy模式的最大区别所在

    总结:

      State模式很好地实现了对象的状态逻辑和动作实现的分离,状态逻辑分布在State的派生类中实现,而动作实现则可以放在Context类中实现(这也是为什么State派生类需要拥有一个指向Context的指针)。这使得两者的变化相互独立,改变State的状态逻辑可以很容易复用Context的动作,也可以在不影响State派生类的前提下创建Context的子类来更改或替换动作实现。

  • 相关阅读:
    Git工作原理
    将博客搬至CSDN
    Hive常见文件存储格式
    Hadoop进入安全模式源码分析
    Hadoop RPC简介
    hive自定义UDF函数
    hive性能调优之表设计层面调优
    flowable 启用慢 且启动不起来 报错看不懂
    数据结构和算法基础
    css: 边宽弧度
  • 原文地址:https://www.cnblogs.com/programmer-wfq/p/4668263.html
Copyright © 2020-2023  润新知