PlantUML 的 7 个常见反模式

puml.online

这篇不是讲 PlantUML 怎么用,是讲 PlantUML 的 7 种「能跑,但是烂」写法。每条都是被同事代码评审 / 自己回看旧图踩过坑后总结的。

1. 一张图塞 200 行

最常见的反模式之一。一张时序图想表达 12 个服务、40+ 步骤,评审者根本看不下去。

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
30
31
@startuml
title 一个完整的下单流程
participant 用户
participant APP
participant 推荐
participant H5
participant 购物车
participant 订单
participant 库存
participant 支付
participant 账务
participant 风控
participant 物流
participant 推送
用户 -> APP: 浏览
APP -> 推荐: 拉推荐
推荐 --> APP: 推荐列表
APP -> H5: 跳转 H5
H5 -> 购物车: 加入购物车
购物车 -> 订单: 下单
订单 -> 库存: 锁定库存
库存 --> 订单: ok
订单 -> 支付: 请求支付
支付 -> 风控: 风险评估
风控 --> 支付: ok
支付 -> 账务: 扣款
账务 --> 支付: ok
支付 --> 订单: 成功
订单 --> H5: 200
... (下略 30 行)
@enduml

正确做法是按业务步骤切片

1
2
3
4
5
6
7
8
9
10
11
12
13
@startuml
title 下单流程 - 浏览到加入购物车
participant 用户
participant APP
participant 推荐
participant H5
用户 -> APP: 浏览
APP -> 推荐: 拉推荐
推荐 --> APP: 推荐列表
APP -> H5: 跳转 H5
H5 --> 用户: 看商品
用户 -> H5: 加入购物车
@enduml

一张图 5-8 个步骤,最多 12 个。再多就拆。

2. 节点没命名

1
2
3
4
5
@startuml
A -> B: hello
B --> C
C -> A: ack
@enduml

ABC 是隐式节点,渲染出来是 :" " 一些乱码。最起码:

1
2
3
4
5
6
7
8
9
@startuml
actor Alice
participant "Backend" as BE
database "User DB" as DB
Alice -> BE: hello
BE -> DB: query
DB --> BE: result
BE --> Alice: ack
@enduml

actor / participant / database / queue / boundary / control / entity 这些关键字用起来,渲染出来即漂亮又符合 UML 规范。

3. 时序图只画同步调用

只画 A -> B: foo 不画返回值,让评审看不到响应:

1
2
3
@startuml
API -> DB: SELECT
@enduml

植物uml 时序图的灵魂是双向箭头。没返回值评审者无法判断流程怎么走。

1
2
3
4
@startuml
API -> DB: SELECT * FROM users
DB --> API: result
@enduml

哪怕返回失败也要画:

1
2
3
4
5
@startuml
API -> DB: SELECT
DB --> API: timeout
API -> API: fallback to cache
@enduml

4. 用 sequence 表达分支

有人遇到 if/else 也硬塞时序图:

1
2
3
4
5
6
7
@startuml
FE -> API: submit
note over API: 如果成功就...
API --> FE: success
note over API: 如果失败就...
API --> FE: error
@enduml

这不是 sequence 该表达的东西。用 activity 图:

1
2
3
4
5
6
7
8
9
10
11
12
13
@startuml
start
:FE 提交;
:API 验证;
if (是否通过?) then (yes)
:写入数据库;
:返回 200;
else (no)
:记录日志;
:返回 400;
endif
stop
@enduml

或者用 sequence 里的 alt / else

1
2
3
4
5
6
7
8
9
10
@startuml
FE -> API: submit
alt 验证通过
API -> DB: write
API --> FE: 200
else 验证失败
API -> DB: log
API --> FE: 400
end
@enduml

5. 类图滥用继承

最常见的。

1
2
3
4
5
6
7
8
9
10
11
12
@startuml
class Cat
class Dog
class Animal
Animal <|-- Cat
Animal <|-- Dog
class ServiceA
class ServiceB
class BaseService
BaseService <|-- ServiceA
BaseService <|-- ServiceB
@enduml

不是所有 Is-A 关系都得用 <|--。组合、依赖、关联也是常见关系:

1
2
3
4
5
6
7
@startuml
class Animal {
-food: Food
}
class Food
Animal --> Food : eats
@enduml

类图默认关联箭头是细虚线 / 实现是带空心三角的虚线,区分开看起来清晰。

6. 主题拉满

最惨的一种图:把 CSS 美感带入到 UML 图,所有美化都没意义。

1
2
3
4
5
6
7
8
9
10
11
12
@startuml
skinparam class {
BackgroundColor gold
BorderColor red
FontColor white
FontSize 18
}
skinparam stereotypeCBackgroundColor yellow
class A
class B
A --> B
@enduml

正常图:

1
2
3
4
5
@startuml
class A
class B
A --> B
@enduml

颜色越少越专业。

7. 不绑定图源

最大的组织级反模式:图渲染成 PNG 之后,源 PlantUML 扔了。

1
2
3
docs/
architecture/
full.png # 这张图谁都不知道怎么改

半年后某个模块改了,没人来同步这张图,架构图慢慢变成「考古发现」。

正确做法:

1
2
3
4
docs/
architecture/
full.puml
full.svg # 渲染产物

源文件和渲染产物一起 commit,CI 自动 re-render。

反模式 → 重构对照表

反模式 影响 重构动作
200 行一张图 看不懂 按业务步骤拆成 4-5 张
节点没命名 渲染错乱 participant / actor / database
时序图没返回值 流程方向不清 全部加响应箭头
用 sequence 表达分支 评审难理解 改 activity 或用 alt
类图滥用继承 设计扭曲 用组合 / 关联
主题拉满 图浮夸 默认主题或简洁皮肤
不绑图源 图腐烂 .puml + .svg 同时 commit

评审 checklist

看到别人的 PlantUML PR 时问这几个问题:

  • 这张图能不能拆成更小的图?
  • 节点全部命名了?
  • 时序图每个调用有响应?
  • 用对了图类型(时序 / 类 / 活动 / 用例)?
  • 主题没拉满?
  • 修改时是否能同步更新?
  • 源文件 commit 了?
  • 标题: PlantUML 的 7 个常见反模式
  • 作者: puml.online
  • 创建于 : 2026-07-29 14:40:00
  • 更新于 : 2026-08-14 21:34:29
  • 链接: https://puml.online/blog/plantuml-anti-patterns/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。