一、状态机图是啥?—— 对象的“行为说明书” 📖
关键字:状态机图、对象状态、状态转换、事件、动作
🧠
状态机图是描述
单个对象生命周期行为
的图:它展示对象在不同“状态”下的表现,以及“事件”触发下状态如何转换,核心是
“状态→事件→动作→新状态”的循环
。
🤖 类比:
如果对象是“电梯”,状态机图就是电梯的“运行手册”——展示电梯的状态(待机、上升、下降、开门),以及事件(按楼层按钮、到达楼层、超时)触发的状态转换(待机→上升、上升→到达楼层→开门)。
✍️ 核心作用:
- 清晰展示对象的行为逻辑:明确“对象在什么状态下,遇到什么事件,会做什么动作,变成什么新状态”;
- 捕捉程序中的事件逻辑:帮助开发者梳理“事件触发的条件和结果”;
- 避免事件时序错误:通过状态转换顺序,确保代码中事件的执行顺序正确。
二、状态机图的“零件”:状态+转换+事件+动作 🧩
关键字:简单状态、初始/终态、转换、事件、监护条件、动作、复合状态
👆 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)实现:用状态机图定义状态和转换,框架自动处理状态切换的逻辑,减少手动判断的代码冗余。