核心问题
这个流程到底有哪些状态,哪些跳转合法?
工程困境
订单流程用 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 的形式出现。