STM32 GPIO驱动L298N双H桥直流电机正反转与PWM调速
2026/11/6 4:13:23
状态机是描述业务流程的核心工具。很多需求说不清楚,就是因为没有画状态机:状态有哪些、能否回退、谁能操作。这篇给你5个常见状态机模板。
状态机是描述对象状态变化的核心工具,由3个要素组成:
业务场景:电商订单从创建到完成的全流程状态管理
状态列表:
状态流转规则:
待支付 --[支付]--> 已支付 待支付 --[取消]--> 已取消 已支付 --[发货]--> 已发货 已支付 --[退款]--> 已退款 已发货 --[确认收货]--> 已完成 已发货 --[退货]--> 已退款 不允许的流转: - 已完成 不能回退到其他状态(终态) - 已取消 不能回退到其他状态(终态) - 已退款 不能回退到其他状态(终态) - 已发货 不能回退到已支付(已发货不能取消) 权限控制: - 用户:可以支付、取消、确认收货、申请退款 - 商家:可以发货、同意退款、拒绝退款 - 系统:可以自动取消(超时未支付,如30分钟) 异常处理: - 支付超时:30分钟未支付,自动取消订单 - 发货超时:7天未发货,自动退款 - 确认收货超时:15天未确认收货,自动确认收货PRD写法:
订单状态机设计: 【状态列表】 1. 待支付:订单已创建,等待用户支付 2. 已支付:用户已支付,等待商家发货 3. 已发货:商家已发货,等待用户确认收货 4. 已完成:用户已确认收货,订单完成 5. 已取消:订单已取消(用户取消或超时自动取消) 6. 已退款:订单已退款(用户申请退款或退货) 【状态流转规则】 | 当前状态 | 触发事件 | 目标状态 | 触发条件 | 权限要求 | 是否可回退 | |---------|---------|---------|---------|---------|----------| | 待支付 | 支付 | 已支付 | 支付成功 | 用户 | 否 | | 待支付 | 取消 | 已取消 | - | 用户/系统 | 否 | | 已支付 | 发货 | 已发货 | - | 商家 | 否 | | 已支付 | 退款 | 已退款 | 退款成功 | 用户/商家 | 否 | | 已发货 | 确认收货 | 已完成 | - | 用户/系统 | 否 | | 已发货 | 退货 | 已退款 | 退货成功 | 用户/商家 | 否 | 【不可逆状态】 已完成、已取消、已退款(终态,不能回退) 【状态变更日志】 记录:谁、何时、从哪个状态、变更到哪个状态、原因、操作IP业务场景:请假、报销、采购等审批流程的状态管理
状态列表:
状态流转规则:
待提交 --[提交]--> 审批中 审批中 --[通过]--> 已通过 审批中 --[驳回]--> 已驳回 审批中 --[撤回]--> 已撤回 已驳回 --[重新提交]--> 审批中 不允许的流转: - 已通过 不能回退(终态) - 已撤回 不能回退(终态) - 待提交 不能直接到已通过(必须经过审批) 权限控制: - 申请人:可以提交、撤回、重新提交 - 审批人:可以通过、驳回 - 系统:可以自动驳回(超时未审批,如3天) 多级审批: - 一级审批:部门经理审批 - 二级审批:总监审批 - 三级审批:总经理审批 - 状态:审批中(一级)→ 审批中(二级)→ 审批中(三级)→ 已通过PRD写法:
审批状态机设计: 【状态列表】 1. 待提交:申请已创建,但未提交审批 2. 审批中:申请已提交,等待审批人审批 3. 已通过:审批已通过 4. 已驳回:审批被驳回,可以重新提交 5. 已撤回:申请人主动撤回申请 【状态流转规则】 | 当前状态 | 触发事件 | 目标状态 | 触发条件 | 权限要求 | 是否可回退 | |---------|---------|---------|---------|---------|----------| | 待提交 | 提交 | 审批中 | - | 申请人 | 是 | | 审批中 | 通过 | 已通过 | - | 审批人 | 否 | | 审批中 | 驳回 | 已驳回 | - | 审批人 | 是 | | 审批中 | 撤回 | 已撤回 | - | 申请人 | 否 | | 已驳回 | 重新提交 | 审批中 | - | 申请人 | 是 | 【不可逆状态】 已通过、已撤回(终态,不能回退) 【多级审批】 请假审批流程: 1. 申请人提交 → 审批中(一级) 2. 部门经理审批 → 审批中(二级)或已通过(≤3天)或已驳回 3. 总监审批 → 审批中(三级)或已通过(≤7天)或已驳回 4. 总经理审批 → 已通过或已驳回业务场景:客服工单从创建到完成的全流程状态管理
状态列表:
状态流转规则:
待分配 --[分配]--> 处理中 处理中 --[提交验收]--> 待验收 待验收 --[验收通过]--> 已完成 待验收 --[验收不通过]--> 处理中 已完成 --[关闭]--> 已关闭 处理中 --[关闭]--> 已关闭(客户主动关闭) 权限控制: - 客服:可以分配、关闭 - 工程师:可以提交验收、关闭(自己的工单) - 客户:可以验收、关闭(自己的工单) - 系统:可以自动关闭(超时未处理,如7天) 异常处理: - 分配超时:24小时未分配,自动分配给默认工程师 - 处理超时:7天未处理,自动升级给主管 - 验收超时:3天未验收,自动验收通过业务场景:项目管理中任务的状态管理
状态列表:
状态流转规则:
未开始 --[开始]--> 进行中 进行中 --[暂停]--> 已暂停 已暂停 --[继续]--> 进行中 进行中 --[完成]--> 已完成 任意状态 --[取消]--> 已取消(未开始、进行中、已暂停都可以取消) 不允许的流转: - 已完成 不能回退(终态) - 已取消 不能回退(终态) 权限控制: - 负责人:可以开始、暂停、继续、完成 - 创建人:可以取消 - 项目经理:可以取消、重新分配 异常处理: - 超时未开始:任务创建后7天未开始,自动提醒负责人 - 超时未完成:任务预计完成时间已过,自动提醒负责人业务场景:用户会员账号的状态管理
状态列表:
状态流转规则:
正常 --[冻结]--> 冻结 冻结 --[解冻]--> 正常 正常 --[注销]--> 注销 冻结 --[注销]--> 注销 不允许的流转: - 注销 不能回退(终态,不能恢复) - 正常 不能直接到注销(需要先冻结,或用户主动申请注销) 权限控制: - 管理员:可以冻结、解冻、注销 - 用户:可以申请注销 - 系统:可以自动冻结(违规操作,如3次密码错误) 异常处理: - 违规冻结:用户违规操作,系统自动冻结,7天后自动解冻 - 注销确认:用户申请注销,需要7天冷静期,7天后确认注销状态机名称:订单状态机 【状态列表】 1. 待支付:订单已创建,等待用户支付 2. 已支付:用户已支付,等待商家发货 3. 已发货:商家已发货,等待用户确认收货 4. 已完成:用户已确认收货,订单完成 5. 已取消:订单已取消(用户取消或超时自动取消) 6. 已退款:订单已退款(用户申请退款或退货) 【初始状态】 待支付(订单创建时的默认状态) 【状态流转规则】 | 当前状态 | 触发事件 | 目标状态 | 触发条件 | 权限要求 | 是否可回退 | 备注 | |---------|---------|---------|---------|---------|----------|------| | 待支付 | 支付 | 已支付 | 支付成功 | 用户 | 否 | - | | 待支付 | 取消 | 已取消 | - | 用户/系统 | 否 | 超时30分钟自动取消 | | 已支付 | 发货 | 已发货 | - | 商家 | 否 | - | | 已支付 | 退款 | 已退款 | 退款成功 | 用户/商家 | 否 | - | | 已发货 | 确认收货 | 已完成 | - | 用户/系统 | 否 | 超时15天自动确认 | | 已发货 | 退货 | 已退款 | 退货成功 | 用户/商家 | 否 | - | 【不可逆状态】 已完成、已取消、已退款(终态,不能回退) 【可回退状态】 无(所有状态转换都是单向的) 【状态变更日志】 记录字段: - 操作人:谁执行的操作(用户ID、商家ID、系统) - 操作时间:何时执行的操作 - 原状态:从哪个状态 - 新状态:变更到哪个状态 - 操作原因:为什么执行这个操作(可选) - 操作IP:操作时的IP地址(可选) 【异常处理】 1. 支付超时:30分钟未支付,自动取消订单 2. 发货超时:7天未发货,自动退款 3. 确认收货超时:15天未确认收货,自动确认收货问题:使用"进行中"、"处理中"等模糊词汇,导致状态含义不明确。
❌ 错误示例: 状态:进行中 问题:进行中是什么意思?是已支付还是已发货? ✅ 正确示例: 状态:已支付、已发货、已完成 每个状态都有明确的含义问题:没有明确哪些状态可以转换,哪些不可以,导致开发实现时出现错误。
❌ 错误示例: 状态流转:待支付可以到已支付 问题:已支付可以回退到待支付吗?已发货可以回退到已支付吗? ✅ 正确示例: 状态流转规则: - 待支付 --[支付]--> 已支付(不可回退) - 已支付 --[发货]--> 已发货(不可回退) - 已发货 --[确认收货]--> 已完成(不可回退)问题:状态数量过多(如20+个),导致状态机复杂度增加,难以维护。
❌ 错误示例: 订单状态:待支付、支付中、已支付、发货中、已发货、运输中、已到达、待签收、已签收、已完成、取消中、已取消、退款中、已退款... 问题:状态太多,难以理解和维护 ✅ 正确示例: 订单状态:待支付、已支付、已发货、已完成、已取消、已退款 使用主状态+子状态的方式: - 主状态:已支付 - 子状态:支付中、支付成功、支付失败问题:没有明确每个状态下哪些角色可以执行哪些操作,导致权限混乱。
❌ 错误示例: 状态:已支付 操作:发货 问题:谁可以发货?用户可以发货吗?系统可以发货吗? ✅ 正确示例: 状态:已支付 操作:发货 权限:只有商家可以发货,用户和系统不能发货问题:没有考虑超时、异常情况的处理,导致状态卡住。
❌ 错误示例: 状态:待支付 问题:如果用户30分钟未支付,订单会一直处于待支付状态吗? ✅ 正确示例: 状态:待支付 异常处理:30分钟未支付,自动取消订单,状态变为已取消问题:没有记录状态变更的详细信息,导致问题排查困难。
❌ 错误示例: 状态变更:只记录新状态,不记录原状态、操作人、操作时间 问题:无法追溯状态变更历史,问题排查困难 ✅ 正确示例: 状态变更日志: - 操作人:用户ID或商家ID或系统 - 操作时间:2025-01-01 10:00:00 - 原状态:待支付 - 新状态:已支付 - 操作原因:用户支付成功答:建议使用主状态+子状态的方式,或者合并相似的状态。
方案1:主状态+子状态
方案2:合并相似状态
答:建议明确哪些状态可回退、哪些不可回退。一般:终态(已完成/已取消)不可回退。
可回退的场景:
不可回退的场景:
答:按照以下步骤设计:
答:可以使用状态模式或状态表的方式实现。
方案1:状态模式
// 伪代码 class OrderState { function canTransitionTo(targetState) { // 检查是否可以转换到目标状态 } function transitionTo(targetState) { // 转换到目标状态 } }方案2:状态表
// 伪代码 const stateTransitionTable = { '待支付': { '支付': '已支付', '取消': '已取消' }, '已支付': { '发货': '已发货', '退款': '已退款' } };答:测试以下场景:
答:可以从以下方面优化:
生成状态机思维导图