广告

C++ 状态设计模式实战:如何实现一个简单的状态机(含示例代码)

状态设计模式的核心原理与应用场景

定义与核心角色

在软件设计中,状态设计模式通过将对象的行为委托给表示当前状态的独立对象,从而避免大量的条件分支。Context 持有一个指向 State 的引用,不同状态对象实现了不同的行为。

这样做的好处是让行为的变化随状态而变化,提高可维护性便于扩展,也有助于将状态转换逻辑集中到一个地方而不是分散在大量的 if-else 中。

适用场景与优点

当一个对象的行为取决于内部状态且这些状态会发生变化时,状态设计模式是一个很自然的选择。它有助于把与状态相关的逻辑从对象的主逻辑中解耦出来。

它还能让新增状态变得简单,因为每个状态都是一个独立的实现,不需要修改 Context 的代码即可新增状态,符合开闭原则。

C++实现状态设计模式的要点

核心类的职责与接口设计

在 C++ 实现中,State 通常是一个纯虚接口,定义一个统一的 handle(Context&) 方法;Context 保存当前状态的指针,并提供改变状态的能力。

每个具体状态如 OnStateOffState 实现 handle(Context&) 来执行对应的行为和状态转移,保持状态之间的解耦。要点在于通过多态实现行为的切换。

内存管理与性能注意

使用 智能指针(如 std::unique_ptr)来管理状态对象的生命周期,避免手动内存释放带来的错误。状态对象通常无状态或可复用,可以频繁创建和替换。

尽量让状态对象保持短小、无副作用,通过 Context 的 setState 交由状态对象控制转换,减小耦合。

一个简单的状态机实战示例(含示例代码)

需求背景与设计思路

本节用一个最小的演示来展示状态设计模式在 C++ 中的实现:一个简单的灯开关状态机,初始状态为 OFF,通过一次切换达到 ON,再次切换回 OFF,循环往复。该案例强调 Context 如何持有状态对象,以及 State 实现具体行为 的分离。

设计要点包括:State 接口的纯虚方法Context 持有状态指针、以及 状态之间的互相切换。通过示例代码可以直观感受状态模式的优雅。

完整实现代码示例

下面给出一个可直接编译的 C++ 实现。它展示了如何以状态设计模式组织一个简单的状态机以及如何通过一个事件触发切换。

#include <iostream>
#include <memory>class Context; // 前向声明,用于 State 接口中的 handle// 状态接口
class State {
public:virtual ~State() = default;virtual void handle(Context& ctx) = 0;
};// 具体状态:开启
class OnState;// 具体状态:关闭
class OffState;class Context {
public:Context();void setState(std::unique_ptr<State> s) { state = std::move(s); }void pressSwitch() { if (state) state->handle(*this); }
private:std::unique_ptr<State> state;
};// 开启状态的实现
class OnState : public State {
public:void handle(Context& ctx) override {std::cout << "灯已开启,切换到关闭状态" << std::endl;ctx.setState(std::make_unique<OffState>());}
};// 关闭状态的实现
class OffState : public State {
public:void handle(Context& ctx) override {std::cout << "灯已关闭,切换到开启状态" << std::endl;ctx.setState(std::make_unique<OnState>());}
};// Context 构造函数实现,需要在对象创建时设定初始状态
Context::Context() : state(std::make_unique<OffState>) {}int main() {Context ctx;// OFF -> ONctx.pressSwitch();// ON -> OFFctx.pressSwitch();// OFF -> ONctx.pressSwitch();return 0;
}

C++ 状态设计模式实战:如何实现一个简单的状态机(含示例代码)

广告

后端开发标签