订单系统里最头疼的bug往往长这样:用户在已发货状态又发起一次退款申请,财务对不上账。根源是状态流转没有约束。状态机就是解决这类问题的模型,全名有限状态机,缩写FSM。
电商订单常见的状态有待支付、已支付、已发货、已完成、已关闭,谁能处在什么状态、什么操作触发什么跳转,全部写进规则里,扯皮会少一大半。
三要素说清楚
状态机只有三样东西:状态、事件、动作。系统任一时刻只处在一个状态,收到事件后按事先定义的规则跳到下一状态,顺便执行动作。十字路口红绿灯就是例子:绿、黄、红是状态,定时器到点是事件,切换灯色是动作。
Moore和Mealy怎么选
Moore型输出只由当前状态决定,输出稳定没有毛刺;Mealy型输出还受当前输入影响,反应更快,状态数也能更少,各有取舍。写Verilog时多数人用三段式:状态寄存、次态逻辑、输出逻辑分开,综合和仿真都友好。
软件里更常见的是switch写法,一个变量存当前状态,每个case里判断事件:
switch (state) { case IDLE: if (event == PAY_OK) state = PAID; break; case PAID: if (event == SHIP_DONE) state = SHIPPED; break; }状态一多就改用状态表,把当前状态加事件得到次态和动作,列成表格,加状态只加一行,不容易漏。画状态转移图也有必要:圆圈代表状态,箭头代表跳转,箭头上标触发事件。评审时业务方看得懂图,看不懂代码,需求对不齐的问题一大半出在状态定义上。
哪些场景值得上状态机
- 订单、审批流这类业务流程,状态和动作都要留痕。
- 嵌入式控制,电饭煲的加热保温预约、洗衣机的进水洗涤漂洗脱水都是典型。
- 协议解析和词法分析,正则引擎底层就是状态机。
一个实用判断:状态超过三个,或者跳转规则开始出现谁都能跳到谁的时候,就先画图再动手写代码,能省掉大量if-else地狱。