1、状态模式(State):当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象的状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
UML图如下:
2、状态模式的好处与用处
好处是将与特定状态相关的行为局部化,并且将不同的状态的行为分割开来,将特定的状态相关的行为都放入一个对象中,由于所有与状态相关的代码都存在于某个ConcreteState中,所有通过定义新的子类可以很容易地增加新的状态和转换。
这样做的目的就是为了消除庞大的条件分支语句。状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖,好比把整个版面改成一个又一个的活字,此时就容易维护和扩展了。
3、什么时候应该考虑使用状态模式呢?
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时。
4、C++代码实现
- #include <iostream>
- #include <string>
- using namespace std;
- class Context;
- /* State类,抽象状态类,定义一个接口以封装
- 与Context的一个特定状态相关的行为 */
- class State
- {
- public:
- string name;
- virtual void Handle(Context * p_context) = 0;
- };
- /* Context类,维护一个ConcreteState子类
- 的实例这个实例定义当前的状态 */
- class Context
- {
- private:
- State * p_state;
- public:
- //定义Context的初始状态
- Context(State * p_state) {
- Context::p_state = p_state;
- }
- State * GetState() {
- return p_state;
- }
- //设置新状态
- void SetState(State * p_state) {
- State * p_temp = Context::p_state;
- delete p_temp;
- Context::p_state = p_state;
- cout << p_state->name << endl;
- }
- //对请求做处理,并设置下一个状态
- void Request() {
- p_state->Handle(this);
- }
- };
- /* ConcreteState类,具体状态,每一个子类实现
- 一个与Context的一个状态相关的行为 */
- class ConcreteStateA : public State
- {
- public:
- ConcreteStateA() {
- this->name = "ConcreteStateA";
- }
- void Handle(Context * p_context);
- };
- class ConcreteStateB : public State
- {
- public:
- //设置ConcreteStateB的下一个状态是
- //ConcreteStateA
- void Handle(Context * p_context) {
- p_context->SetState(new ConcreteStateA());
- }
- ConcreteStateB() {
- this->name = "ConcreteStateB";
- }
- };
- //设置ConcreteStateA的下一个状态是
- //ConcreteStateB
- void ConcreteStateA::Handle(Context * p_context){
- p_context->SetState(new ConcreteStateB());
- }
- int main()
- {
- Context context(new ConcreteStateA());
- context.Request();
- context.Request();
- context.Request();
- context.Request();
- return 0;
- }