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

转载于:https://www.cnblogs.com/programmer-wfq/p/4668263.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值