核心问题

这个流程到底有哪些状态,哪些跳转合法?

工程困境

订单流程用 100 个 if-else 处理:

if (order.status === "created" && paid) ...
if (order.status !== "shipped" && refund) ...

很快没人知道订单能不能从 canceled 变回 paid。

思想模型

有限状态机:

created -> paid -> shipped -> completed
created -> canceled
paid -> refunded

状态机的价值不是画图好看,而是列出合法迁移和非法迁移。

好做法

payOrder(orderId)
shipOrder(orderId)
cancelOrder(orderId)
refundOrder(orderId)

不要让任何地方随便写:

order.status = "paid"

Atlas Action

拿一个流程,画三列:

状态 | 允许迁移 | 禁止迁移

然后补测试,尤其测试非法迁移。

小结

如果你不画状态机,状态机会以 bug 的形式出现。