1. 状态模式概述与糖果机案例引入
状态模式是GoF 23种设计模式中行为型模式的一种,它允许对象在内部状态改变时改变其行为。这种模式特别适合处理那些对象行为取决于其状态,并且需要在运行时根据状态改变行为的场景。
想象一个糖果自动售货机的工作流程:当机器处于"无硬币"状态时,投入硬币会触发状态转换;而在"有硬币"状态时,转动曲柄又会触发新的状态变化。如果用传统的if-else或switch-case来实现,代码会变得冗长且难以维护。这正是状态模式大显身手的地方。
提示:状态模式的核心思想是将每个状态的行为封装到独立的类中,通过委托给当前状态对象来处理请求,从而消除庞大的条件分支语句。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 状态模式实现详解
2.1 State接口设计
State接口定义了所有具体状态类必须实现的方法,对应糖果机可能的各种操作:
cpp复制struct State {
virtual void insertQuarter() = 0; // 投币
virtual void ejectQuarter() = 0; // 退币
virtual void turnCrank() = 0; // 转动曲柄
virtual void dispense() = 0; // 发放糖果
virtual ~State() = default; // 虚析构函数
};
接口设计的几个关键点:
- 每个方法对应糖果机的一个外部可触发操作
- 使用纯虚函数确保子类必须实现所有行为
- 添加虚析构函数保证多态删除时的正确性
2.2 具体状态类实现
以"有硬币"状态为例,展示具体状态类的典型实现:
cpp复制class HasQuarterState : public State {
public:
explicit HasQuarterState(GumballMachine* machine)
: machine(machine) {
srand(static_cast<unsigned>(time(nullptr)));
}
void insertQuarter() override {
std::cerr << "已经投入硬币,不能再投入" << std::endl;
}
void ejectQuarter() override {
std::cout << "硬币退回" << std::endl;
machine->setState(machine->getNoQuarterState());
}
void turnCrank() override {
std::cout <<
