状态机(State Machine)详解:原理、优缺点与 C++ 实战示例

一、概念

状态机(State Machine,FSM) 是一种描述系统行为的数学模型,用来表示系统在不同状态之间的转换关系。简单理解就是:程序在任意时刻都处于某一种"状态",根据不同的事件或条件,切换到其他状态。状态机在嵌入式开发、游戏开发、协议解析、业务流程控制等场景中被广泛使用。

二、状态机的核心组成

一个典型的状态机包含以下几个要素:

状态:系统当前所处的状态,如:Idle、Running、Stop

事件:触发状态变化的条件,如按钮点击、超时、收到数据

状态转移:从一个状态到另一个状态的变化规则

动作:在状态切换或状态中执行的操作

三、为什么要使用状态机?

优点:

逻辑清晰,结构清楚;将复杂逻辑拆解为多个状态,避免大量 if-else 嵌套。

可维护性强;修改某个状态逻辑时,不影响其他状态。

扩展方便;新增状态或行为时,不需要重构整体代码。

非常适合流程控制;(设备控制、业务流程、通信协议)

缺点:

状态过多时复杂度增加;状态数量爆炸;前期设计成本较高;需要提前规划状态和转换关系;不适合非常简单的逻辑;只有几个判断时使用状态机反而显得"重"

四、典型应用场景

1.游戏角色行为(待机 / 行走 / 攻击 / 死亡)

2.订单系统(创建 → 支付 → 发货 → 完成)

3.网络通信协议(如 TCP 状态机)

4.嵌入式设备控制(洗衣机、电梯、空调)

五、C++ 状态机示例(订单流程)

示例需求

订单状态如下:

bash 复制代码
CREATED → PAID → SHIPPED → COMPLETED
         ↓
       CANCELED
cpp 复制代码
#include <iostream>
using namespace std;

enum class OrderState {
    CREATED,
    PAID,
    SHIPPED,
    COMPLETED,
    CANCELED
};


class OrderStateMachine {
public:
    OrderStateMachine() : state(OrderState::CREATED) {}

    void pay() {
        if (state == OrderState::CREATED) {
            state = OrderState::PAID;
            cout << "订单已支付" << endl;
        } else {
            invalidOperation("支付");
        }
    }

    void ship() {
        if (state == OrderState::PAID) {
            state = OrderState::SHIPPED;
            cout << "订单已发货" << endl;
        } else {
            invalidOperation("发货");
        }
    }

    void complete() {
        if (state == OrderState::SHIPPED) {
            state = OrderState::COMPLETED;
            cout << "订单已完成" << endl;
        } else {
            invalidOperation("完成");
        }
    }

    void cancel() {
        if (state == OrderState::CREATED || state == OrderState::PAID) {
            state = OrderState::CANCELED;
            cout << "订单已取消" << endl;
        } else {
            invalidOperation("取消");
        }
    }

private:
    OrderState state;

    void invalidOperation(const string& op) {
        cout << "当前状态下无法执行操作:" << op << endl;
    }
};

//使用示例:
int main() {
    OrderStateMachine order;

    order.pay();
    order.ship();
    order.complete();

    return 0;
}

运行结果:

bash 复制代码
订单已支付
订单已发货
订单已完成

六、与if-else/switch-case相比的优势:

1.逻辑更清晰,状态机把系统行为拆分成"状态 + 状态转换",比层层嵌套的 if-else 更直观。

2.可维护性更好,每个状态职责明确,修改或新增状态不容易影响其他逻辑。

3.扩展性强,当业务变复杂时,只需要增加状态或转移规则,不需要重写大量判断代码。

4.更符合业务模型,状态机直接对应现实中的业务流程(如订单状态、设备状态),代码更易理解。

5.减少逻辑错误,明确的状态流转能避免非法状态和混乱跳转。

相关推荐
linux开发之路2 小时前
C++高性能日志库开发实践
c++·c++项目·后端开发·c++新特性·c++校招
niucloud-admin2 小时前
java服务端——controller控制器
java·开发语言
刻BITTER2 小时前
在TRAE 上安装PlatformIO
c++·单片机·嵌入式硬件·arduino
永远都不秃头的程序员(互关)3 小时前
C++动态数组实战:从手写到vector优化
c++·算法
夏幻灵3 小时前
JAVA基础:基本数据类型和引用数据类型
java·开发语言
水力魔方3 小时前
武理排水管网模拟分析系统应用专题5:模型克隆与并行计算
数据库·c++·算法·swmm
cike_y3 小时前
Spring-Bean的作用域&Bean的自动装配
java·开发语言·数据库·spring
十八度的天空4 小时前
第01节 Python的基础语法
开发语言·python
OliverH-yishuihan4 小时前
在win10上借助WSL用VS2019开发跨平台项目实例
linux·c++·windows