目录
1. 前言
状态模式作为设计模式的一种,主要用于根据状态的改变执行不同的动作,它允许一个对象在其内部状态改变时改变它的行为。状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
2. 基本原理
状态模式一般由三个角色组成,分别是Context、State和ConcreteState。其中,Context是直接与调用者对接的类,State是一个抽象类,是一个总的状态描述,调用者并不直接使用State类,而是使用具体化了的ConcreteState类。
ConcreteState类很重要,它包含了当前状态所要执行的动作信息。
3. UML模型
4. 例程
以下以一个简单的驾驶场景为例,我们的交通灯有三种状态,分别是红灯、绿灯和黄灯。我们在驾驶过程中,需要根据不同的交通灯状态来决定驾驶的行为。下面一段程序就是实现了“红灯停,绿灯行,黄灯亮了等一等”。
#include <iostream>
#include <string>
/** 抽象状态类. */
class LightState
{
public:
virtual void HandleState(std::string& light) = 0;
virtual ~LightState() {}
};
/** 具体状态-红灯. */
class RedLightState: public LightState
{
public:
void HandleState(std::string& light) override {
light = "Red";
std::cout << "Stop!" << std::endl;
}
};
/** 具体状态-绿灯. */
class GreenLightState: public LightState
{
public:
void HandleState(std::string& light) override {
light = "Green";
std::cout << "Go!" << std::endl;
}
};
/** 具体状态-黄灯. */
class YellowLightState: public LightState
{
public:
void HandleState(std::string& light) override {
light = "Yellow";
std::cout << "Slow down and wait!" << std::endl;
}
};
/** 状态向下文. */
class TrafficLightContext
{
public:
TrafficLightContext(LightState* state) : state(state){
}
void SetState(LightState* state)
{
this->state = state;
}
void Operation()
{
std::string light = "Unknown";
state->HandleState(light);
std::cout << "Current light is: " << light << std::endl;
}
private:
LightState* state;
};
int main(int argc, char* argv[])
{
TrafficLightContext context(new RedLightState());
context.Operation();
context.setState(new GreenLightState());
context.Operation();
context.setState(new YellowLightState());
context.Operation();
return 0;
}