首页/开发/系统分析与架构设计速查/复合状态与历史伪状态
需求分析与建模61 条

复合状态与历史伪状态

复合状态内部嵌套子状态机,可划分多个区域并行运行;浅历史 H 记住最近子状态,深历史 H* 恢复嵌套层次;用于复杂流程的分层建模。

复合状态与历史伪状态

当一个对象的状态机节点过多时,可以用复合状态把子状态机包进一个状态里:外部只看到一个状态,内部自己维持多条子状态。复合状态内可以划出多个区域(region)并行运行;历史伪状态用来记住“上次离开时的子状态”,浅历史 H 恢复一层,深历史 H* 恢复全部嵌套层次。它们的作用是把复杂流程分层描述,而不是把所有组合平铺成一张巨图。

基本信息

复合状态状态内部再含状态机,可简化外部转换
区域(region)同一复合状态内并行运行的多条子状态机
历史伪状态浅历史 H 恢复一层,深历史 H* 恢复全部嵌套层次
进入语义进入复合状态默认走其初始伪状态,除非显式指向历史伪状态

典型使用场景

  • 订单与运单流转:运输中这类长阶段内部再分干线、分拨、末端
  • 设备连接管理:连接态内部再分注册、鉴权、保活子状态
  • 审批流程建模:审批中内部包含多级审批与退回分支
  • 游戏或仿真状态:并行区域分别管理角色状态与场景状态
  • 中断恢复场景:用历史状态恢复中断前的子状态,避免从头开始

复合状态示例(PlantUML 片段)

复合状态示例(PlantUML 片段)
state 运单流 {
  [*] --> 待揽收
  待揽收 --> 运输中 : 揽收
  state 运输中 {
    [*] --> 干线
    干线 --> 末端 : 到达分拨
  }
  运输中 --> 已签收 : 妥投
}

历史伪状态对照

用法恢复范围适用
浅历史 H只恢复到复合状态最近一次的直接子状态一层嵌套即可表达的场景
深历史 H*恢复全部嵌套层次的子状态多层嵌套且需要原样恢复的场景
无历史重新进入初始子状态每次进入都从头开始的流程

使用要点

  • 复杂状态机建议分层:先画一级状态,再把每个状态单独展开,避免一张图几百个节点
  • 历史状态只在确有恢复语义时使用,滥用会让行为依赖隐式记忆
  • 并行区域之间只通过消息或事件交互,不共享可变状态
  • 命名用业务词汇而非技术词汇,评审时业务方能直接核对
复杂状态机建议分层:先画一级状态,再把每个状态单独展开,避免一张图几百个节点;分层的图也更便于按子状态机分配实现责任。
深历史恢复会让对象行为依赖隐式记忆:测试要构造“进入-离开-再进入”的序列才能覆盖,遗漏时问题只在特定重入路径上出现。

易错点

  • 并行区域之间共享可变状态,产生难以复现的竞态,问题只在特定交错下出现
  • 滥用深历史恢复,对象行为依赖隐式记忆,测试难以构造且易漏分支
  • 复合状态层级过深,实际实现里转换分散在多处,状态机与代码逐渐不一致
  • 把并行区域当成并发执行保证:区域是逻辑并行表达,不等于运行时线程安全
  • 状态命名为技术术语(如“step3”),业务评审无法核对,语义漂移无人发现

数据来源与参考

  • OMG UML 2.5.1 规范
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌