PlantUML 时序图高级用法:fragment、step、ref
时序图语法在面试的时候很喜欢问,但能在真实项目里画得让评审看懂——能用得相对少。这篇整理高级语法。
fragment 语法速查(重复一遍) 1 2 3 4 5 6 7 alt / else / end — 分支 opt / end — 可选块 loop / end — 循环 par / else / end — 并行 critical / option / end — 关键段 + 异常 break / end — 跳出 note / end note — 注释
写「订单支付流程」必带的两三个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @startuml title 支付流程 用户 -> 网关: 发起支付 网关 -> 风控: 评估 alt 风险通过 网关 -> 银行: 扣款 critical 失败回滚 网关 -> 银行: 退款 option 退款失败 网关 -> 客服: 人工介入 end option end critical 网关 --> 用户: 200 else 风险拒绝 网关 --> 用户: 403 end @enduml
实际练习:时序图 + 类图 + 状态图组合 一个完整的「订单生命周期」用三张图表达:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @startuml actor User participant "Order Service" as Os participant "Payment Service" as Ps participant "Inventory Service" as Is database "Order DB" as Odb == 提交订单 == User -> Os: POST /orders Os -> Is: 锁定库存 Is --> Os: ok Os -> Odb: insert Odb --> Os: order_id == 支付 == Os -> Ps: pay(order_id) group payment logic alt success Ps -> Odb: update status=paid else fail Ps -> Odb: update status=failed Os -> Is: 解锁库存 end end == 通知 == Os --> User: 200 + order_id @enduml
group / end 把一段动作归类,可在评审里被折叠。
ref 和 step ref 引用别张图1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @startuml title 登录主流程 participant FE participant API participant Auth == 注册 == User -> FE: 打开注册页 FE -> API: POST /signup API -> Auth: 创建用户 Auth --> API: ok API --> FE: 200 note right of User: 在主流程中已绘制 @enduml
ref over A, B : label 用于指向已经存在的描述:
1 2 3 4 5 6 7 8 9 10 11 @startuml participant FE participant API FE -> API: POST /login note right of FE: 已被 ref 覆盖 ref over FE : 登录页加载完成 FE -> API: 提交表单 @enduml
step(系统响应延迟) step 500ms 让 PlantUML 渲染时将箭头延迟一段时间:
1 2 3 4 5 6 7 8 9 @startuml Client -> Server: 请求 step 500ms Server --> Client: 200 step 1000ms Client -> Server: 下一个请求 @enduml
适合画「动画时序图」但博客静态截图看不到效果。
skinparam 在时序图 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @startuml skinparam sequence { ArrowColor #2F4858 ArrowFontColor #1F2328 LifeLineBorderColor #A31F34 LifeLineBackgroundColor #FAFAFA ParticipantBorderColor #2F4858 ParticipantBackgroundColor #FAFAFA ActorBorderColor #A31F34 ActorBackgroundColor #FAFAFA BoxBorderColor #2F4858 BoxBackgroundColor #FAFAFA FontColor #1F2328 } actor 用户 participant 网关 participant 后端 database 数据库 用户 -> 网关: 注册 网关 -> 后端: create_user 后端 -> 数据库: INSERT 数据库 --> 后端: ok 后端 --> 网关: 200 网关 --> 用户: 200 @enduml
调成 CRDT 风格:暗底白字 + 红色箭头。
group / box / partition 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @startuml box "客户端" participant FE end box box "服务端" participant API end box box "数据层" database DB end box FE -> API: HTTP API -> DB: SQL @enduml
box ... end box 框住一组对象,便于评审分清楚谁负责什么。
box 内的 partition 1 2 3 4 5 6 7 8 9 10 11 12 13 @startuml box over 服务端 #FAFAFA partition API层 { participant 鉴权 participant 业务 } partition 数据层 { database DB } end box @enduml
separator(箭头提示) 自消息(实线 + 空箭头) 1 2 3 4 5 6 7 8 9 10 11 @startuml actor 用户 participant 浏览器 participant 后端 用户 -> 浏览器: 点击按钮 浏览器 -> 浏览器: 自己校验 浏览器 -> 后端: POST /submit @enduml
自我调用(自消息) 1 2 3 4 5 6 7 @startuml class OrderService OrderService -> OrderService: 处理订单 @enduml
异步消息(虚线 + 实箭头) 1 2 3 4 5 6 7 @startuml API ->> Queue: 发布事件 Queue ->> Worker: 异步消费 Worker -->> API: ACK @enduml
->> 实线箭头表示异步发送。-->> 虚线返回。
删除消息(叉号) 1 2 3 4 @startuml API ->x Cache: 删除 @enduml
->x 表示消息被丢弃。
multiplicity 1 2 3 4 5 6 7 8 9 10 11 12 @startuml "用户1" --> "请求1" : msg "用户2" --> "请求2" : msg "用户3" --> "请求3" : msg note right of "请求1" 实际生产中每分钟上千条 多用户并发 end note @enduml
时序图中其实没法直接表达「多」实例,但通过命名约定表达 multiplicity。
嵌套 alt / par 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @startuml FE -> API: submit alt 第一次提交 par API -> DB: insert else API -> Cache: clear end else 重试 loop 重试 3 次 API -> DB: update end end @enduml
alt / par / loop 可以嵌套。
实战略招:在文档中嵌入时序图 每篇文章放一段最关键的时序图:
1 2 3 4 5 6 7 8 ## 登录接口时序  源码(login.puml): @startuml ... @enduml
这样评审者看到渲染 SVG,debug 时能直接复制源文本改改再贴。
反模式 1. 时序图里有「每个人都打一行」 1 2 3 4 5 6 User -> Browser Browser -> Backend Backend -> Auth Auth -> DB DB -> Auth @enduml
不写消息和返回的箭头,看起来像流程图,不是时序图。
2. 时序图混用活动图风格 1 2 3 4 if (...) then ... -> ... -> ... @enduml
循环和分支不属于时序图范畴;用活动图。
3. 时序图拉太长 一张时序图最好 5-15 个步骤、3-5 个 lifeline。超过就拆。
4. 时序图没标注角色
不画 actor / participant、不用 database / queue,会丢失业务信息。
评审 checklist
时序图最佳实践
每个时序图只回答一个问题 :「登录」「支付」「下单」分别一张图。
lifeline 数量 ≤ 5 。
消息有明确动词 :POST /login 比 login 好。
关键路径用普通箭头,异步用 ->> 。
异常路径标红或者注释 :评审一眼能看到 error flow。
导出 SVG 给 PR :SVG 比 PNG 更清晰。