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
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 }
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
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 }
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 }
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的子类来更改或替换动作实现。