时序图 vs 活动图 vs 状态图:三种图的区别、各自适合表达什么(附选择清单)
同一个需求到底该画时序图、活动图还是状态图?本文从信息密度、表达对象、常见误解与反例修正出发,给你一套可复用的选择清单,并提供研发/测试/产品协作的落地画法。
很多人第一次在文档里被要求“补一张 UML 图”,脑子里冒出的第一个问题不是怎么画,而是:到底该画哪一种?
- 你想表达“服务 A 调服务 B,超时重试、回调、补偿”这种交互先后关系 → 大概率是时序图(Sequence Diagram / 序列图)
- 你想表达“从提交订单到发货的业务流程怎么流转、哪些节点并行、谁审批”这种流程编排 → 大概率是活动图(Activity Diagram)
- 你想表达“订单/工单/登录会话从创建到结束经历哪些状态、什么事件触发状态变化、哪些状态不可达”这种对象生命周期 → 大概率是状态图(State Machine Diagram / Statechart)
下面用一套“你要回答的问题是什么”的视角,把三者的区别、误用场景、以及可交付的选择清单讲透。你是产品/研发/测试/架构/写文档的人,照着这篇就能在评审里把图画对、讲清、还能经得起追问。
想把文字交互快速变成专业图?可以顺手用在线时序图生成器把草稿落地: 手打时序图 - 时序图在线制作 文字粘进去会自动排版,左侧编辑器可以点选“生命线/消息/组合片段”,右侧实时预览,最后一键导出 SVG/PNG/JPEG/draw.io,写文档和画图两不误。
1)先别背定义:用“你要回答的问题”来选图
把需求描述换成一个问题,选图就会很自然:
A. 你要回答“谁先调用谁?先后顺序是什么?同步还是异步?”
选:时序图
典型问题:
- A 调 B 之前必须先拿 token 吗?
- 超时之后是重试还是降级?重试次数在哪里体现?
- 回调是另起一条链路还是同一条?
- 幂等校验是在网关做还是在业务服务做?
时序图的“主语”是:参与者之间的消息交互(对象/组件/服务/外部系统)。
B. 你要回答“流程怎么走?哪些节点可以并行?有哪些分支/泳道/审批?”
选:活动图
典型问题:
- 订单创建后进入哪个处理队列?
- 人工审核失败怎么回流?
- 退款要走哪些步骤?哪些步骤可以并行?
- 哪些节点是“必须”,哪些是“可选”?
活动图的“主语”是:活动(动作)与控制流/数据流,更像“可执行/可追踪”的流程描述。
C. 你要回答“这个对象有哪些状态?状态如何变化?哪些事件触发迁移?非法状态是什么?”
选:状态图
典型问题:
- 订单为什么会出现“已支付但未发货且不可退款”的奇怪组合?
- 工单从“待处理”到“处理中”需要哪些事件?
- 一个登录会话的生命周期是什么?
- 某个状态能不能直接跳到另一个状态?需要什么守卫条件?
状态图的“主语”是:单个对象(或聚合)的状态机。
2)三种图一句话定义(够用版)
- 时序图:在时间轴上描述多个参与者之间的消息交互,强调“谁→谁→什么时候”。
- 活动图:描述一个流程/业务/算法的步骤、分支、并行与泳道,强调“怎么做→做到哪一步”。
- 状态图:描述一个对象在不同状态之间的迁移、触发事件与守卫条件,强调“现在是什么→在什么条件下变成什么”。
如果你只记一条:
交互顺序(时序图) / 流程编排(活动图) / 生命周期与约束(状态图)
3)对比:信息密度与“读者能从图上得到什么”
下面不是教科书对比,而是文档评审里最常见的“读者需求”。
时序图:让读者看懂“交互协议”和“边界条件”
你画得好的时序图,读者能从图上直接回答:
- 哪些调用是同步阻塞、哪些是异步投递
- 返回值是否重要(是否要画虚线返回消息)
- 哪些分支会触发补偿/重试/降级
- 哪个组件承担幂等/鉴权/缓存/限流的职责
适合的读者:研发、测试、架构、对接方。
活动图:让读者看懂“流程”和“责任边界”
你画得好的活动图,读者能从图上直接回答:
- 整体流程的开始/结束条件
- 分支条件与并行点
- 不同角色/系统的职责(泳道)
- 是否存在“遗漏路径”(比如异常未处理)
适合的读者:产品、运营、测试、研发(做端到端流程的人)。
状态图:让读者看懂“状态约束”与“非法组合”
你画得好的状态图,读者能从图上直接回答:
- 允许的状态集合是什么(枚举边界清晰)
- 哪些事件能触发迁移、迁移条件是什么
- 哪些状态不可达/不允许回退
- 如何设计状态字段/状态码,避免出现“自相矛盾”的状态组合
适合的读者:研发(尤其后端/领域建模)、测试(用例覆盖)、产品(规则对齐)。
4)典型场景:同一件事,用三种图分别表达什么
用“下单-支付-发货”这个常见链路举例,你会更直观。
4.1 你要对齐“支付回调重试、幂等、补偿”——用时序图
时序图里你会画出:
- 用户/前端 → 订单服务:创建订单
- 订单服务 → 支付网关:发起支付
- 支付网关 → 订单服务:异步回调(可能重复)
- 订单服务:签名校验 → 幂等判断 → 状态更新 → 发货事件投递
- 回调超时/失败:网关重试;订单服务落库后再异步补偿
这里的关键不是“有哪些步骤”,而是:谁给谁发消息、先后顺序、失败路径。
4.2 你要对齐“业务流程与角色职责”——用活动图
活动图里你会画出:
- 泳道:用户/前端、订单系统、仓储系统、客服/人工审核(如果有)
- 节点:提交订单 → 风控校验 → 支付 → 生成出库单 → 发货
- 分支:风控失败/支付失败/缺货
- 并行:发货后并行发送通知、开票、积分
这里的关键是:流程是怎么编排的、谁负责哪一步、哪些步骤可以并行。
4.3 你要对齐“订单状态字段的设计与测试用例”——用状态图
状态图里你会画出:
- 状态:已创建、待支付、已支付、待发货、已发货、已完成、已取消、退款中、已退款
- 事件:支付成功回调、用户取消、超时关闭、发货完成、确认收货、发起退款、退款成功
- 守卫条件:已支付才能发货;已发货后取消改为“退货/退款”;退款中禁止重复发起
这里的关键是:有哪些合法状态、哪些迁移被允许、迁移条件是什么。
5)三种图各自的“最小元素集”:画到什么粒度才专业
很多图“看起来对但不专业”,原因通常不是画错了,而是缺了关键元素或粒度不一致。
5.1 时序图最小元素集(够评审)
- 参与者/生命线:用户、前端、服务、DB、外部系统(命名要明确)
- 消息:同步调用/异步消息(箭头类型要一致)
- 激活条(Activation):强调处理时间/阻塞关系(可选,但复杂链路建议加)
- 组合片段(Fragments):
alt表示分支(if/else)opt表示可选路径loop表示重试/循环par表示并行
- 异常路径:至少要交代“超时/失败/重试/补偿”在哪发生
常见“粒度坑”:
- 把每个内部函数都画成一条消息 → 图爆炸,读者看不见主线
- 完全不画异常路径 → 图很“顺滑”,但评审最关心的恰恰是失败怎么处理
5.2 活动图最小元素集
- 开始/结束:流程边界要清楚
- 活动节点:动作尽量用动词短语(例如“校验库存”“创建出库单”)
- 控制流:箭头方向要能一眼看出主路径
- 分支/合并:条件写在边上(例如“库存不足”)
- 泳道(Swimlane):明确责任方/系统边界(强烈建议)
- 并行/同步:Fork/Join,避免“看起来并行其实是串行”
常见“粒度坑”:
- 把活动图画成“页面点击流程图”但没有泳道 → 责任边界糊成一团
- 分支条件写成“是/否”但不说明判断依据 → 测试写不出用例
5.3 状态图最小元素集
- 状态集合:状态名是名词/形容词(例如“待支付”“已取消”),要互斥
- 事件/触发器:迁移边上写触发事件(例如“paySucceeded”)
- 守卫条件:
[condition],把“只有满足 X 才能迁移”说清楚 - 动作(可选):进入/退出动作(entry/exit)或迁移动作(比如“发送通知”)
- 终止状态(可选):有些对象确实会结束(例如会话/任务)
常见“粒度坑”:
- 把状态当成步骤(比如“校验库存”“扣减库存”)→ 那是活动,不是状态
- 把多个字段拼成一个“组合状态”(比如“已支付+已发货+已评价”)→ 很快会出现非法组合
6)选择清单:用 10 个问题快速决定画哪种图
下面是一份“开会前 2 分钟自检”的清单。你不必每次都答完,但答得越多,越不容易选错。
- 我是否需要表达多个参与者之间的调用先后?(是 → 时序图)
- 我是否需要表达异步、回调、重试、超时、补偿?(是 → 时序图优先)
- 我是否需要表达一个端到端的业务流程?(是 → 活动图)
- 我是否需要表达角色/系统的责任边界?(是 → 活动图+泳道)
- 我是否需要表达并行与汇合?(是 → 活动图 或 时序图的
par,看你在讲流程还是讲交互) - 我是否需要定义一个对象的状态枚举?(是 → 状态图)
- 我是否需要说明哪些迁移不允许、哪些是非法?(是 → 状态图)
- 我是否需要指导测试写用例,覆盖状态迁移?(是 → 状态图)
- 我的读者更关心“怎么协作对接”还是“业务规则是否自洽”?(对接 → 时序图;自洽 → 状态图)
- 我是否打算把图作为接口契约的一部分(例如对外开放平台)?(是 → 时序图通常更直观)
一句话决策法(会议里很好用)
- “我们先把交互协议讲清楚”→ 时序图
- “我们先把流程编排讲清楚”→ 活动图
- “我们先把状态与规则边界讲清楚”→ 状态图
7)常见误解与反例:为什么你会选错(以及怎么修正)
反例 1:用活动图去画微服务之间的调用链
现象:你画了一张活动图,里面写“调用用户服务→调用订单服务→调用库存服务→调用支付服务”。
问题:活动图擅长表达“流程步骤”,但不擅长表达:
- 同步/异步差异
- 谁调用谁、返回值是否重要
- 超时重试、回调、并发
修正:把“服务之间的调用链”改成时序图:
- 每个服务一条生命线
- 同步调用/异步消息用不同箭头
- 重试用
loop,分支用alt
反例 2:用时序图去表达“审批流程”
现象:为了画“提交→主管审批→财务审批→归档”,你画了时序图,把每一步画成消息。
问题:审批流程的本质是“流程编排+角色泳道”,时序图会让读者误以为这些都是“接口调用”,而忽略了:
- 人工节点的等待时间
- 责任边界
- 并行审批、退回重提
修正:改成活动图:
- 用泳道区分“申请人/主管/财务/系统”
- 用分支表达“同意/驳回”
- 用并行表达“多方会签”
反例 3:用状态图去画“算法步骤”
现象:你想描述一个风控规则引擎,画出“收集特征→计算分数→命中规则→输出结果”当成状态。
问题:这些是“步骤”,不是对象的“稳定状态”。状态图里每个状态应当能回答“此时对象处于什么情况”,而不是“正在执行哪一步”。
修正:如果你在讲规则引擎如何处理请求,用活动图;如果你在讲“风控工单”生命周期(待审核/已通过/已拒绝),才用状态图。
反例 4:把“订单状态”画成一个超级复杂的状态图,但迁移条件全靠口头补充
现象:状态图上只有箭头,没有触发事件/守卫条件。
问题:这会导致图看起来“很完整”,但实际无法落地:研发不知道什么时候能迁移,测试不知道用什么条件覆盖边界。
修正:至少补齐两类信息:
- 迁移触发:谁触发(用户操作/系统任务/外部回调)
- 守卫条件:什么前置条件满足才允许迁移(例如“已支付且未发货”)
8)落地建议:同一个项目里,三种图怎么配合最省力
你不必在每个需求上都画三种图。更高效的组合通常是:
- 对外/对接链路:先出一张“主路径 + 关键失败路径”的时序图(把契约说清楚)
- 业务流程:再出一张活动图(把角色与流程编排说清楚)
- 核心领域对象:最后给关键对象补一张状态图(把状态与约束固化成规则)
这样做的好处:
- 产品评审看活动图就能对齐流程
- 研发评审看时序图就能对齐接口/异常处理
- 测试评审看状态图就能对齐用例覆盖
如果你经常在文档里反复改图,建议用能“边改边预览”的工具:左侧用结构化编辑器点选生命线、消息、alt/opt/loop/par 片段,右侧实时预览;改完一键导出成 SVG/PNG 或 draw.io 文件,直接贴到 PRD/设计文档/测试用例里。很多团队省的不是画图时间,而是来回对齐的沟通成本。
需要的话可以试试这个: 手打时序图 - 时序图在线制作 支持 AI 生成草稿,你再按团队规范微调,比从空白开始画舒服很多。
9)FAQ:高频争论点一次回答
Q1:我能不能用一张图把三者都表达?
可以,但一般不建议。
- 如果你把流程、交互、状态全部塞进一张图,读者会在不同维度之间来回切换,结果“什么都画了但什么都没讲清”。
- 更好的做法是:一张图只回答一个问题。需要多维度时,配套两张图(例如“时序图 + 状态图”)往往更清晰。
Q2:画时序图时,返回消息要不要画?
经验法则:
- 返回值对读者理解至关重要(例如“拿到 token”“返回支付单号”)→ 画返回消息或在消息上标注返回内容
- 返回只是“成功/失败”且不会影响后续分支 → 可以不画,避免噪声
关键不是“必须画虚线”,而是“读者能不能从图上看懂关键数据怎么流动”。
Q3:活动图里的并行,能不能用时序图的 par 代替?
看你在讲什么:
- 讲“流程编排”→ 活动图更自然(Fork/Join、泳道)
- 讲“并行交互的消息关系”→ 时序图的
par更自然(并行消息的发生关系)
Q4:状态图适合表达数据库表的状态字段吗?
很适合,而且是最常见、也最容易带来质量提升的用法。
因为状态图能逼你回答:
- 状态集合是否互斥?
- 迁移是否可达?有没有死路?
- 触发事件是谁?能否重复?
- “回滚/补偿/撤销”到底允许到哪一步?
这些问题如果不在设计阶段说清楚,通常会在上线后变成“脏数据 + 线上补丁”。
Q5:学生/作业场景怎么办?老师要求 UML 图但不说哪种。
按题目问法来选:
- 题目强调“对象之间如何交互”→ 时序图
- 题目强调“业务流程/算法步骤”→ 活动图
- 题目强调“对象状态变化/状态转移表”→ 状态图
写作业时一个小技巧:先用一句话写出“我这张图要回答的问题”,放在图标题下方,基本不会选错。
10)交付前自检:让你的图在评审里更抗打
不管你画的是哪一种,交付前做一次自检,能少掉很多“我以为你表达的是另一个意思”的沟通成本。
时序图自检
- 参与者命名是否明确(避免“Service1/Service2”)
- 同步/异步是否区分清楚
- 至少覆盖 1 条关键失败路径(超时/失败/重试/补偿)
- 分支条件写在
alt框上,而不是靠口头解释
活动图自检
- 泳道是否齐全(谁负责哪一步)
- 分支条件是否可测试(不是“正常/异常”这种泛词)
- 并行点是否有 Join 回来(避免流程悬空)
- 是否画清楚开始与结束边界
状态图自检
- 状态是否互斥且完整(有没有“其他”这种含糊状态)
- 迁移边是否写清触发事件与守卫条件
- 是否存在不可达状态/循环陷阱
- 是否能直接映射到代码与测试用例(状态枚举、事件、条件)
如果你现在手里有一段“文字版交互/流程”,但还没决定画哪张图:
- 先用上面的 10 个问题选定图种
- 再把主路径画出来
- 最后补齐 1~2 条异常路径或边界条件
需要把时序图快速落地、并导出可贴到文档里的图片/源文件,可以直接用这个工具做初稿: 手打时序图 - 时序图在线制作