状态模型,就是当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
状态模型结构图
状态模型基本代码
#include <iostream>
using namespace std;
class Context;
class State { // 抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为
public:
virtual void Handle(Context* c) = 0;
virtual ~State() {}
};
class Context { // 维护一个ConcreteState子类的实例,这个实例定义为当前状态
private:
State* state;
public:
Context(State* s) { state = s; }
void Request() { // // 对请求做处理,并设置下一状态
if (state == NULL) return;
state->Handle(this);
}
void SetState(State* s) { state = s; }
virtual ~Context() {
if (state != NULL) {
delete state;
state = NULL;
}
}
};
// 具体状态类,每一个字类实现与Context的一个状态相关行为
class ConcreteStateA : public State {
public:
void Handle(Context* c);
};
class ConcreteStateB : public State {
public:
void Handle(Context* c);
};
class ConcreteStateC : public State {
public:
void Handle(Context* c);
};
void ConcreteStateA::Handle(Context* c) {
cout << "ConcreteStateA" << endl;
c->SetState(new ConcreteStateB());
}
void ConcreteStateB::Handle(Context* c) {
cout << "ConcreteStateB" << endl;
c->SetState(new ConcreteStateC());
}
void ConcreteStateC::Handle(Context* c) {
cout << "ConcreteStateC" << endl;
c->SetState(new ConcreteStateA());
}
int main() {
State* s = new ConcreteStateA();
Context* c = new Context(s);
c->Request(); // ConcreteStateA 切换状态
c->Request(); // ConcreteStateB
c->Request(); // ConcreteStateC
delete s;
delete c;
return 0;
}
应用场景
状态模式通过把各种状态转换转移逻辑分布到State的子类之间,来减少相互间的依赖。当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式了。
优点:将与特定状态有关的行为局部化,并且将不同状态的行为分割开来。