学设计模式的时候,GoF(Gang of Four,四人组)状态模式几乎是必考题。课堂上它逻辑清晰,能优雅地消灭一大片switch语句,看起来完美无瑕。
但真把它用到实际业务里,很多人会撞上一堵隐形的墙——代码越写越乱,每个状态类都跟其他状态纠缠不清。问题出在哪?
状态模式的核心:状态自己决定下一步
GoF状态模式的设计思路,是把主对象的逻辑拆散,分给各个状态对象去处理。听起来很合理,但有个关键设定:状态类自己得负责触发状态切换。
拿最简单的红绿灯举例:红灯→绿灯→黄灯→红灯,循环往复。用GoF写,红灯类里就得new一个绿灯对象出来。这个闭环场景下没问题,规则永远不会变。
可现实中的业务规则,从来不会这么老实。
业务一变,状态类就成蜘蛛网
假设市议会突然规定:午夜到凌晨5点,红绿灯必须闪黄灯。这时候你得打开红灯类和黄灯类,加时间判断,加新状态。状态越多,类之间的耦合越重,代码越改越乱。
再看电商订单:Pending(待处理)不一定到Shipped(已发货),可能直接跳到Cancelled(已取消);Shipped也可能变成Returned(已退货)。状态转移根本不是一条直线。
如果用GoF硬写,PendingState得知道所有可能跳转的目标状态,类会膨胀到难以维护。
FSM的解法:把控制权收回来
有限状态机(FSM,Finite State Machine)换了个思路:状态类只管自己内部的行为规则,状态之间的跳转交给一个中央控制器(Orchestrator)统一管理。
用配置表定义状态转移规则,代码立刻清爽很多。订单状态机可以写成一张规则表:PENDING状态下收到PAID事件→进入SHIPPED;收到CANCELLED事件→进入CANCELLED。控制器只负责查表、跳转、执行对应逻辑。
非法跳转直接拦截,报错提示,逻辑一目了然。
什么时候用哪个?
判断标准其实很简单:状态转移是否固定不变。
如果状态是封闭循环,比如红绿灯、电梯调度,规则永远不会变,GoF状态模式完全够用,代码还直观。
如果状态转移复杂多变,比如订单、审批流、工单系统,业务规则随时可能调整,FSM的集中式管理明显更合适。改规则只动配置表,不用翻遍所有状态类。
教科书教的是基础,但真实业务永远是复杂的。选型之前,先想清楚你的状态是死是活。
热门跟贴