对象图相对小众,但在调试、文档化状态、举具体例子时极好用——它是类图在某个瞬间的「快照」。
一句话定义
对象图描绘特定时刻系统中的一组实例(对象)和它们之间的链接。而类图描述「有哪些类型」,对象图描述「现在这些类型各有什么实例、它们怎么连的」。
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 32 33 34 35 36
| @startuml object "用户实例" as user1 { id = 1024 name = "Alice" email = "alice@example.com" }
object "订单实例" as order1 { id = "ORD-2026-001" status = "PAID" total = 299.0 }
object "商品实例" as product1 { id = "P-001" name = "PlantUML 入门" price = 49.0 }
object "商品实例" as product2 { id = "P-002" name = "PlantUML 模板" price = 99.0 }
user1 --> order1 : 下单 order1 --> product1 : 包含 order1 --> product2 : 包含 order1 -- "200.0" : 计算 1 order1 -- "99.0" : 计算 2
note right of order1 这是某一时刻的状态 实际数据来自生产环境 end note @enduml
|
渲染出来:
- 对象框:底部还显示「type:Order」之类的引用类型名(按 instance model)
- 状态变量:显示在对象框里
- 链接:实线带标签(实例之间的引用关系)
元素清单
| 元素 |
关键字 |
渲染 |
| 实例 |
object "name" as alias |
矩形,下划线(UML)表示对象 |
| 字段值 |
id = "..."(对齐) |
对象框里 |
| 实例间引用 |
--> |
实线 + 标签 |
| 多种引用 |
--> "label1" --> "label2" |
多重标注 |
| 注释 |
note right of |
折叠角注释 |
对象图的 4 种用法
1. 描述某状态下实例的样子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @startuml
object "购物车实例" as cart1 { customerId = 1024 couponCode = null total = 0.0 }
object "购物车项 A" as item1 { productId = "P-001" quantity = 2 lineTotal = 98.0 }
object "购物车项 B" as item2 { productId = "P-002" quantity = 1 lineTotal = 99.0 }
cart1 --> item1 cart1 --> item2
@enduml
|
调试时 dump 对象结构的对象图,比粘贴一长串打印输出好读。
2. 演示一个业务流程中各对象的关系
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 32 33 34
| @startuml
object "游客浏览器" as browser { cookie = null session = null }
object "服务器请求实例" as req1 { method = "POST" path = "/login" body = "..." }
object "认证服务实例" as auth1 { dbConnection = "..." cacheHit = false }
object "用户数据实例" as user { id = 1024 email = "alice@example.com" failedAttempts = 0 }
object "审计日志写入实例" as audit { eventType = "LOGIN_ATTEMPT" }
browser --> req1 : 发起 req1 --> auth1 : 调用 auth1 --> user : 查询 auth1 --> audit : 记录
@enduml
|
3. 设计模式示例的「当时状态」
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @startuml
object "具体主题" as concreteSubject { state = 42 }
object "观察者 A 实例" as obs1 { name = "Logger" }
object "观察者 B 实例" as obs2 { name = "Metrics" }
concreteSubject -> obs1 : 持有引用 concreteSubject -> obs2 : 持有引用
note right of concreteSubject Observer pattern 主题维护观察者列表 状态变化时通知列表中所有观察者 end note
@enduml
|
4. 描述配置、初始化、迁移等特定场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @startuml
object "Kafka 集群配置" as kafkaConfig { brokers = "kafka-0:9092,kafka-1:9092" topicPrefix = "puml-events" partitionCount = 6 replicationFactor = 3 }
object "消费者组 A" as cgA { groupId = "user-events-consumer" consumerCount = 3 }
object "消费者组 B" as cgB { groupId = "audit-events-consumer" consumerCount = 1 }
kafkaConfig --> cgA : 当前 kafkaConfig --> cgB : 当前
@enduml
|
实战:调试一个订单状态不一致
调试时 dump 出一个真实生产环境的「对象图」:
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 32 33 34 35 36 37 38 39 40 41
| @startuml
object "订单 A" as oA { id = "ORD-2026-001" status = "PAID" paidAt = "2026-07-29 14:00" customerId = 1024 }
object "订单 B" as oB { id = "ORD-2026-002" status = "PROCESSING" customerId = 1024 }
object "用户 A" as uA { id = 1024 email = "alice@example.com" vip = true }
object "退款申请 X" as rX { id = "REF-001" orderId = "ORD-2026-001" status = "PENDING_APPROVAL" amount = 299.0 }
oA --> uA : 属于 oB --> uA : 属于 rX --> oA : 关联
note right of rX 关键点: - 退款 X 引用了订单 A - 订单 A 状态是 PAID(不是 REFUNDED) - 在 REFUNDED 标记到来之前,rX 还在 PENDING_APPROVAL - 这是一个合法的「中间态」 end note
@enduml
|
这种图一是贴到 issue 里超有用,二是给团队讲清楚「某个 bug 在该状态下为什么出现」。
对象图 vs 类图
| 维度 |
类图 |
对象图 |
| 描绘 |
类型之间的关系 |
当前实例 + 它们的链接 |
| 语法关键字 |
class |
object |
| 字段 |
类型签名 |
值(实际数据) |
| 关系 |
静态依赖 |
运行时引用 |
| 使用场景 |
设计、文档 |
调试、demo |
| 数量 |
一类一图 |
一时一图(每次状态可能不同) |
两者配合:先类图表达「结构」,再对象图展示「具体实例的当前样子」。
反模式
1. 给对象图加类型信息
1 2 3 4
| object "用户实例" { id: Long // ❌ 这就是类图,不是对象图 name: String }
|
应该是值,不是类型:
1 2 3 4
| object "用户实例" { id = 1024 name = "Alice" }
|
2. 把对象图画得太多太杂
对象图描绘「某一时刻」。超过 10 个对象,请分成多张图。