一、状态机图是啥?—— 对象的“行为说明书”📖
🧠
状态机图是描述 单个对象生命周期行为 的图:它展示对象在不同“状态”下的表现,以及“事件”触发下状态如何转换,核心是“状态→事件→动作→新状态”的循环。
🤖 类比:
如果对象是“电梯”,状态机图就是电梯的“运行手册”——展示电梯的状态(待机、上升、下降、开门),以及事件(按楼层按钮、到达楼层、超时)触发的状态转换(待机→上升、上升→到达楼层→开门)。
✍️ 核心作用:
- 清晰展示对象的行为逻辑:明确“对象在什么状态下,遇到什么事件,会做什么动作,变成什么新状态”;
- 捕捉程序中的事件逻辑:帮助开发者梳理“事件触发的条件和结果”;
- 避免事件时序错误:通过状态转换顺序,确保代码中事件的执行顺序正确。
二、状态机图的“零件”:状态 + 转换 + 事件 + 动作 🧩
👆 1. 状态:对象的“处境”
状态是对象在某一时刻的稳定状态,分为:
- 简单状态:无嵌套的基础状态(比如“审核中”“等待支付”);
- 初始状态:对象生命周期的起点(用“实心小圆”表示);
- 终态:对象生命周期的终点(用“实心小圆 + 外圈”表示);
- 复合状态:包含子状态的嵌套状态(比如“订单处理中”包含“审核中”“发货中”等子状态)。
状态的完整表示包含:
- 入口动作(entry):进入状态时执行的动作(比如进入“审核中”时执行
entry/recordAuditTime()); - 出口动作(exit):离开状态时执行的动作(比如离开“审核完成”时执行
exit/sendNotice()); - 内部活动(do):处于状态时持续执行的动作(比如“等待支付”时执行
do/checkPayTimeout())。
🔄 2. 转换:状态的“切换开关”
转换是状态之间的跳转,由“事件 + 监护条件 + 动作”组成,格式为:[监护条件]/ 动作(事件触发时,若监护条件满足,则执行动作并跳转到新状态)。
if (user.payImmediately()) {// 监护条件:用户立即支付
recordAuditResult(“ 完成 ”); // 动作:记录审核结果
state = “ 审核完成 ”; // 状态转换
}
💬 3. 事件:转换的“触发器”
事件是触发状态转换的“刺激”,常见类型:
- 调用事件:对象收到方法调用(比如
submitOrder()); - 改变事件:对象属性发生变化(比如
payStatusChanged()); - 时间事件 :时间触发的事件(比如
after(30s)表示“30 秒后”)。
📌 4. 监护条件:转换的“门槛”
监护条件是转换触发的“附加条件”(用 [条件] 表示),比如“审核中→审核完成”的监护条件是[用户立即支付]。
三、复杂状态:复合状态与子状态 📦
📦
当对象的状态逻辑复杂时,用 复合状态(包含子状态的状态)来组织:
- 正交复合状态:子状态并行执行(比如“课程学习中”同时包含“视频观看”和“作业完成”两个并行子状态);
- 历史状态:记录复合状态中上次的子状态(用“H”表示),用于“重新进入复合状态时,恢复到之前的子状态”(比如“订单暂停后恢复,回到之前的‘发货中’子状态”)。
🤖 类比:
复合状态像“文件夹”,子状态是文件夹里的“文件”——“订单处理中”文件夹包含“审核中”“发货中”“配送中”等文件,正交复合状态则是“同时打开多个文件并行处理”。
四、状态机图的建模步骤:写好对象的“行为剧本”📋
📌 步骤:
- 确定对象的状态:梳理对象生命周期中的所有稳定状态(比如“订单”的“创建中”“审核中”“等待支付”“完成”);
- 识别触发事件:找出导致状态变化的事件(比如“用户提交订单”“支付超时”);
- 定义状态转换:明确“从哪个状态,经哪个事件,满足什么条件,执行什么动作,到哪个新状态”;
- 添加状态的动作:补充入口 / 出口动作、内部活动;
- 处理复杂状态:对嵌套逻辑使用复合状态,对并行逻辑使用正交复合状态。
✍️ 实战例子:订单状态机图
初始状态→“审核中”(entry/ 记录审核时间)→事件“用户立即支付”+ 监护条件“[支付成功]”→动作“记录支付信息”→转换到“审核完成”(exit/ 发送通知)→终态。
五、状态机图的实战价值:复杂对象的“行为管控”🔧
🚀
在实际开发中,状态机图常用于 复杂对象的行为逻辑梳理——比如电商系统的“订单”、支付系统的“交易”、物流系统的“包裹”等,这些对象的状态多、事件多,通过状态机图可以清晰梳理“状态→事件→动作”的逻辑,避免代码中出现“状态判断混乱”“事件遗漏”等问题。
☁️ 复杂场景:状态机框架的应用
对于超复杂的状态逻辑(比如金融系统的“交易状态”),可以结合状态机框架(如 Spring Statemachine)实现:用状态机图定义状态和转换,框架自动处理状态切换的逻辑,减少手动判断的代码冗余。