定义
状态模式(State Pattern)是一种行为设计模式,它允许对象在内部状态改变时改变其行为,对象看起来似乎修改了其类。状态模式通过将每个状态封装到一个独立的对象中,并且将这些状态对象作为上下文对象的成员来实现状态的切换。
结构
-
Context(上下文) :持有一个
State对象的实例,该实例定义了当前的状态。 -
State(抽象状态) :定义了一个接口,用于封装与 Context 的一个特定状态相关的行为。
-
ConcreteState(具体状态) :实现
State接口,并根据 Context 的状态来实现具体行为。
优点
-
简化状态转换逻辑:通过将每个状态的逻辑封装在独立的类中,使得状态转换的逻辑更加清晰和易于维护。
-
开闭原则:可以轻松地添加新的状态而不需要修改现有的代码。
-
提高灵活性:允许对象的行为在运行时发生变化,使得对象更具有灵活性。
代码示例
以下是一个关于文档发布流程的示例。文档有三种状态:草稿状态、审核中状态和发布状态。每个状态的行为不同,并且可以根据特定条件从一个状态切换到另一个状态,这里的条件为:周一至周三为草稿状态,周四至周五为审核状态,周六至周日为发布状态。
#include <iostream>
#include <string>
class Document;
// 抽象状态类
class State
{
public:
virtual void handleRequest(Document& d) = 0;
virtual ~State() = default;
};
// 上下文类
class Document
{
private:
int weekday = 1; // 周几
State* state; // 状态
public:
Document(State* initialState) : state(initialState) {}
void setState(State* val)
{
state = val;
}
void handleRequest()
{
state->handleRequest(*this);
}
int getDay()
{
return weekday;
}
void setDay(int val)
{
weekday = val;
}
};
// 发布状态
class PublishedState : public State
{
public:
void handleRequest(Document& d) override
{
std::cout << "Today is day" << d.getDay() << ", Document is in Published State." << std::endl;
}
};
// 审核状态
class ModerationState : public State
{
public:
void handleRequest(Document& d) override
{
if (d.getDay() < 6) // 周四至周五为审核状态
{
std::cout << "Today is day" << d.getDay() << ", Document is in Moderation State." << std::endl;
}
else
{
d.setState(new PublishedState());
d.handleRequest();
}
}
};
// 草稿状态
class DraftState : public State
{
public:
void handleRequest(Document& d) override
{
if (d.getDay() < 4) // 周一至周三为草稿状态
{
std::cout << "Today is day" << d.getDay() << ", Document is in Draft State." << std::endl;
}
else
{
d.setState(new ModerationState());
d.handleRequest();
}
}
};
int main()
{
Document* file = new Document(new DraftState());
file->setDay(7);
file->handleRequest();
delete file;
system("pause");
return 0;
}