状态机(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.减少逻辑错误,明确的状态流转能避免非法状态和混乱跳转。

相关推荐
D_evil__13 小时前
【Effective Modern C++】第二章 auto:6. 当auto推导的类型不符合要求时,使用显式类型初始化习惯用法
c++
哈哈不让取名字14 小时前
基于C++的爬虫框架
开发语言·c++·算法
花间相见14 小时前
【JAVA开发】—— Nginx服务器
java·开发语言·nginx
扶苏-su14 小时前
Java---Properties 类
java·开发语言
一条咸鱼_SaltyFish16 小时前
远程鉴权中心设计:HTTP 与 gRPC 的技术决策与实践
开发语言·网络·网络协议·程序人生·http·开源软件·个人开发
我即将远走丶或许也能高飞16 小时前
vuex 和 pinia 的学习使用
开发语言·前端·javascript
沐知全栈开发16 小时前
SQL LEN() 函数详解
开发语言
剑锋所指,所向披靡!16 小时前
C++之类模版
java·jvm·c++
钟离墨笺16 小时前
Go语言--2go基础-->基本数据类型
开发语言·前端·后端·golang
小郭团队17 小时前
1_7_五段式SVPWM (传统算法反正切+DPWM3)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·算法·matlab·dsp开发