时序图怎么画:参与者、消息顺序与生命线
当一件事要经过三四个模块接力完成,流程图就不够用了——它只能表达先后,表达不了「谁对谁发了什么」。时序图补的正是这块:横向是参与者,纵向是时间,每一根箭头都是一次明确的调用。
先列出参与者,再谈顺序
参与者是「会主动发出或接收消息的东西」:用户、前端页面、网关、业务服务、数据库、第三方接口。判断一个角色要不要画进来,标准是它是否既接收又发出消息——只被动的数据对象不必单独成列。
- 参与者从左到右按调用顺序排列,被调用方放在右侧
- 同类型参与者可以并列,例如多个下游服务
- 名称用系统里真实存在的模块名,不要用「系统」这种笼统称呼
- 数量控制在六到八个以内,超过就拆成两张图
同步、异步与返回要分开画
实心箭头表示同步调用:发出后要等结果。开放式箭头表示异步消息:发出后不等,继续往下走。虚线箭头表示返回。把这三类区分清楚,图才能真实反映系统的行为——尤其是「谁在等谁」,这决定了系统的响应时间由什么决定。
- 同步调用画实心实线箭头,简单调用可以省略返回箭头
- 异步消息画开放箭头,必须画出后续处理
- 返回用虚线,并在箭头旁写明返回什么
- 需要严格对应的场景才画激活条(细长方块),否则不要画,容易乱
异常、超时与重试必须画
只画顺利路径的时序图,在评审时基本没有价值,因为工程上出问题的从来是异常分支。超时时间、重试次数、失败后走哪条路,这些才是图上看点最高的内容。
- 超时用时间约束标注(例如「5s 超时」),写在箭头附近
- 重试要画出次数与退避策略,不要只写「失败重试」
- 降级分支画成独立的一条链路,标明触发条件
- 关键幂等点用批注标出,避免重复调用产生脏数据
用片段表达条件与循环
当交互中出现「满足条件才执行」「循环执行」「两种可选方案」时,用带标题的方框(片段)把这些消息框起来。这比在箭头旁边写一堆文字清楚得多,也让图有结构性。
- 条件分支用 alt 框,上下两段分别写条件和结果
- 可选执行用 opt 框,只在条件成立时才画在里面
- 循环用 loop 框,并在标题里写明循环条件
- 片段可以嵌套,但嵌套超过两层就说明这张图该拆了
排布与阅读顺序
时序图的信息密度很高,排布的核心是让纵向的顺序和横向的归属都清晰。参与者顶栏对齐、生命线用虚线贯通到底、消息从高到低严格按时间排,做到这三点基本就不会误读。
- 生命线用浅色虚线,不要用实线抢视觉
- 同一对参与者之间的往返消息尽量紧凑,避免上下拉得很开
- 重要消息加序号,便于评审时逐条讨论
- 图注写明这张图对应哪个场景,例如「下单成功主流程」
常见问题
- 时序图和流程图有什么区别?
- 流程图描述一件事的步骤顺序,不关心谁参与;时序图描述多个对象之间一次交互的消息往来,强调的是「谁对谁说了什么」。跨模块调用、接口设计用时序图,业务流程梳理用流程图。
- 返回箭头要不要每条都画?
- 同步调用在不产生歧义时可以省略返回箭头,让图更清爽。但异步消息和需要标注返回内容的调用必须画,否则读者无法判断数据流向。
- 时序图需要画到多细?
- 以评审时能据此判断实现方案为准。涉及外部接口、数据库操作、缓存读写的地方要细;内部简单的工具方法调用可以合并成一步。
- 如何表达并行处理?
- 用并行片段把同时发出的多条消息框在一起,或者直接用多条并列的异步箭头。需要说明「等全部完成才继续」时,加一条汇合的标注。