状态模式
状态模式定义
状态模式(State),当一个对象的内在状态改变时,允许改变其行为,这个对象看起来是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
状态模式结构图
状态模式结构图如下所示:

图 01 状态模式结构图
状态模式套用代码
1 #include <iostream> 2 using namespace std; 3 4 class Context; 5 class State 6 { 7 public: 8 virtual void Handle(Context* context) = 0; 9 virtual ~State() 10 { 11 12 } 13 }; 14 15 class Context 16 { 17 private: 18 State* state; 19 public: 20 Context(State* state) 21 { 22 this->state = state; 23 } 24 25 State* GetState() 26 { 27 return this->state; 28 } 29 30 void SetState(State* state) 31 { 32 this->state = state; 33 } 34 35 // 释放state指向的内存空间 36 void DeleteState() 37 { 38 delete state; 39 state = NULL; 40 } 41 42 void Request() 43 { 44 state->Handle(this); 45 } 46 47 virtual ~Context() 48 { 49 50 } 51 }; 52 53 class ConcreteStateC : public State 54 { 55 public: 56 virtual void Handle(Context* context) 57 { 58 cout << "C" << endl; 59 context->DeleteState(); 60 context->SetState(new ConcreteStateC()); 61 } 62 63 virtual ~ConcreteStateC() 64 { 65 66 } 67 }; 68 69 class ConcreteStateA : public State 70 { 71 public: 72 virtual void Handle(Context* context) 73 { 74 // 设置ConcreteStateA的下一个状态是ConcreteStateC 75 cout << "A" << endl; 76 context->DeleteState(); 77 context->SetState(new ConcreteStateC()); 78 } 79 80 virtual ~ConcreteStateA() 81 { 82 83 } 84 }; 85 86 87 class ConcreteStateB : public State 88 { 89 public: 90 virtual void Handle(Context* context) 91 { 92 // 设置ConcreteStateA的下一个状态是ConcreteStateA 93 cout << "B" << endl; 94 context->DeleteState(); 95 context->SetState(new ConcreteStateA()); 96 } 97 98 virtual ~ConcreteStateB() 99 { 100 101 } 102 }; 103 104 void main() 105 { 106 ConcreteStateB* b = new ConcreteStateB(); 107 Context* c = new Context(b); 108 109 // 状态不断改变,因为Context中的State变量的指向改变了 110 c->Request(); 111 c->Request(); 112 c->Request(); 113 c->Request(); 114 115 if(b != NULL) 116 { 117 delete b; 118 b = NULL; 119 } 120 121 if(c != NULL) 122 { 123 delete c; 124 c = NULL; 125 } 126 }
状态模式特点
① 状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。就是将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某一个ConcreteState中,所以通过定义新的子类可以很容易地增加新的状态和转换。消除庞大的条件分支语句。
② 状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
③ 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为是,就可以考虑使用状态模式。
④ 策略模式的类图和状态模式的很相像,但是两者的代码与思想相差非常大哦。
状态模式实例应用
状态模式实例应用类图

图 02 状态模式实例应用类图
状态模式实例应用代码
1 #include <iostream> 2 using namespace std; 3 4 class CWork; 5 class CForenoonState; 6 7 class CState 8 { 9 public: 10 virtual void WriteProgram(CWork* w) = 0; 11 virtual ~CState() 12 { 13 14 } 15 }; 16 17 class CWork 18 { 19 private: 20 CState* current; 21 double hour; 22 public: 23 CWork(); 24 25 double GetHour() 26 { 27 return this->hour; 28 } 29 30 void SetHour(double hour) 31 { 32 this->hour = hour; 33 } 34 35 void SetState(CState* state) 36 { 37 this->current = state; 38 } 39 40 // 释放内存 41 void DeleteState() 42 { 43 delete current; 44 current = NULL; 45 } 46 47 void WriteProgram() 48 { 49 current->WriteProgram(this); 50 } 51 52 virtual ~CWork() 53 { 54 DeleteState(); 55 } 56 }; 57 58 // 下午的状态 59 class CAfternoonState : public CState 60 { 61 public: 62 void WriteProgram(CWork* w) 63 { 64 cout << "继续工作" << endl; 65 } 66 67 virtual ~CAfternoonState() 68 { 69 70 } 71 }; 72 73 // 中午的状态 74 class CNoonState : public CState 75 { 76 public: 77 void WriteProgram(CWork* w) 78 { 79 if(w->GetHour() < 13) 80 { 81 cout << "午睡" << endl; 82 } 83 else 84 { 85 w->DeleteState(); 86 w->SetState(new CAfternoonState()); 87 w->WriteProgram(); 88 } 89 } 90 91 virtual ~CNoonState() 92 { 93 94 } 95 }; 96 97 98 // 早上的状态 99 class CForenoonState : public CState 100 { 101 public: 102 virtual void WriteProgram(CWork* w) 103 { 104 if(w->GetHour() < 12) 105 { 106 cout << "开始工作" << endl; 107 } 108 else 109 { 110 w->DeleteState(); 111 w->SetState(new CNoonState()); 112 w->WriteProgram(); 113 } 114 } 115 virtual ~CForenoonState() 116 { 117 118 } 119 }; 120 121 // 为了能够识别CForenoonState的构造函数 122 CWork::CWork() 123 { 124 current = new CForenoonState(); 125 } 126 127 void main() 128 { 129 CWork* project = new CWork(); 130 project->SetHour(12.5); 131 project->WriteProgram(); 132 133 if(project != NULL) 134 { 135 delete project; 136 project = NULL; 137 } 138 }
2014-12-01 20:55:22
浙公网安备 33010602011771号