Mermaid vs PlantUML 类图对比:语法差异、示例与选型
本文只关注类图本身的图形表达能力。 至于 Markdown 支持、文档平台集成、生态插件、渲染服务这些整体工具差异,本文不会展开,相关内容可以看系列总览:Mermaid vs PlantUML:2026 年该选哪个图表即代码工具?。
在这个前提下,结论也很直接:日常用于说明领域模型、服务对象、接口关系和简单继承结构的类图,Mermaid 已经足够;如果你要做更接近正式 UML 的设计归档,尤其是包、命名空间、隐藏细节、关联类、复杂注释和统一样式,PlantUML 更稳。
它们都能表达类名、属性、方法、可见性、继承、组合、聚合、依赖、实现、基数和注解。真正影响选择的,通常不是“谁能不能画继承关系”,而是这张图是否需要更完整的 UML 元素、更强的模型裁剪能力、更复杂的包结构,或者更适合放进架构评审材料。
更准确的判断是:
Mermaid 胜在轻量直接。 对产品文档、README、技术方案和中小型领域模型来说,它的 classDiagram 语法短、可读、容易嵌入 Markdown。只要类数量不多、分组不复杂、样式要求不重,Mermaid 通常不会成为表达瓶颈。
PlantUML 胜在 UML 语义更完整。 它支持更多声明元素,例如 interface、enum、abstract class、record、dataclass、protocol、exception 等,也有更成熟的包、命名空间、隐藏/移除成员、关联类、链接注释、布局辅助和 skinparam 样式能力,更适合复杂设计图和长期维护的架构图。
本文基于官方文档整理,并配合具体案例对比代码和图形效果:
Mermaid vs PlantUML 类图核心差异
| 对比点 | Mermaid | PlantUML | 选择建议 |
|---|---|---|---|
| 类、属性、方法 | 支持 | 支持 | 两者都可以 |
| 可见性 | 支持 +、-、#、~ | 支持 +、-、#、~ | 两者都可以 |
| 静态/抽象成员 | 支持 $ 和 * 标记 | 支持 {static}、{abstract} 等更显式写法 | 正式 UML 图 PlantUML 更清楚 |
| 继承/实现/组合/聚合/依赖 | 支持常见关系 | 支持常见关系 | 两者都可以 |
| 基数 | 支持关系两端标注 | 支持关系两端标注 | 两者都可以 |
| 泛型 | 支持 ~T~,但复杂泛型有限制 | 支持泛型表达 | 复杂类型模型 PlantUML 更合适 |
| 接口/枚举/抽象类 | 通过 annotation 表达 | 有 interface、enum、abstract class 等声明元素 | PlantUML 语义更显式 |
| 包和命名空间 | 支持 namespace | 支持 package、namespace 和多种包样式 | 大型模型 PlantUML 更合适 |
| 隐藏成员和裁剪视图 | 主要依赖配置和少量语法 | 支持 hide、remove、restore、按标签裁剪 | 设计评审 PlantUML 更合适 |
| 注释 | 支持 note 和 note for | 支持方向注释、浮动注释、链接注释、字段/方法注释 | PlantUML 注释能力更细 |
| 关联类 | 不突出 | 支持 association class | 需要严格 UML 语义时选 PlantUML |
| 样式控制 | 支持 classDef、CSS class、主题配置 | 支持 skinparam、颜色、stereotype 样式等 | 统一图形规范 PlantUML 更合适 |
先给一句话结论:
Mermaid 类图适合把结构讲清楚;PlantUML 类图适合把结构、语义、裁剪视图和输出规范一起控制住。
Mermaid 也可以画清楚常见类模型
很多人以为类图只要进入继承、接口、组合、基数,就必须使用 PlantUML。这个判断并不准确。Mermaid 官方类图支持类成员、可见性、返回类型、泛型、常见 UML 关系、基数、annotation、note 和 direction,足以覆盖大多数文档型类图。
下面是一个订单领域模型:Order 拥有多个 OrderItem,使用 PaymentMethod 接口完成支付,并和 Customer 建立关联。
Mermaid 代码和图
classDiagram
direction LR
class Customer {
+String id
+String email
+placeOrder()
}
class Order {
+String id
+OrderStatus status
+Money total
+addItem(productId, quantity)
+checkout() PaymentResult
}
class OrderItem {
+String productId
+int quantity
+Money price
+subtotal() Money
}
class PaymentMethod {
<<Interface>>
+authorize(amount) PaymentResult
}
class CreditCardPayment {
+String token
+authorize(amount) PaymentResult
}
class OrderStatus {
<<Enumeration>>
CREATED
PAID
CANCELLED
}
Customer "1" --> "0..*" Order : places
Order "1" *-- "1..*" OrderItem : contains
Order --> PaymentMethod : uses
PaymentMethod <|.. CreditCardPayment
Order --> OrderStatus
PlantUML 代码和图
@startuml
left to right direction
class Customer {
+id: String
+email: String
+placeOrder()
}
class Order {
+id: String
+status: OrderStatus
+total: Money
+addItem(productId, quantity)
+checkout(): PaymentResult
}
class OrderItem {
+productId: String
+quantity: int
+price: Money
+subtotal(): Money
}
interface PaymentMethod {
+authorize(amount): PaymentResult
}
class CreditCardPayment {
+token: String
+authorize(amount): PaymentResult
}
enum OrderStatus {
CREATED
PAID
CANCELLED
}
Customer "1" --> "0..*" Order : places
Order "1" *-- "1..*" OrderItem : contains
Order --> PaymentMethod : uses
PaymentMethod <|.. CreditCardPayment
Order --> OrderStatus
@enduml
对这种中小型领域模型,Mermaid 已经可以把结构讲清楚。它不是只能画“几个方框加几条线”;类成员、接口标记、枚举标记、组合关系和基数都能表达。
PlantUML 的声明元素更接近正式 UML
两者都能表达接口和枚举,但语义颗粒度不同。Mermaid 通常用 <<Interface>>、<<Enumeration>> 这类 annotation 标记类的性质;PlantUML 可以直接声明 interface、enum、abstract class 等元素。
Mermaid 代码和图
classDiagram
class Repository {
<<Interface>>
+findById(id) Entity
+save(entity)
}
class SqlRepository {
+findById(id) Entity
+save(entity)
}
class BaseEntity {
<<Abstract>>
+String id
+createdAt Date
}
BaseEntity <|-- User
Repository <|.. SqlRepository
PlantUML 代码和图
@startuml
interface Repository {
+findById(id): Entity
+save(entity)
}
class SqlRepository {
+findById(id): Entity
+save(entity)
}
abstract class BaseEntity {
+id: String
+createdAt: Date
}
class User
BaseEntity <|-- User
Repository <|.. SqlRepository
@enduml
Mermaid 的 annotation 很适合文档说明;PlantUML 的声明元素更适合正式建模,因为读者能从语法和图形上同时看出元素类型。
PlantUML 更适合大型类图的裁剪和分组
类图一旦变大,真正困难的不是“能不能画出来”,而是“能不能只展示当前读者需要看的部分”。例如同一套领域模型,在产品说明里可能只展示公开方法,在代码设计评审里可能要展示字段、抽象类、包结构和内部依赖。
PlantUML 在这类场景更自然:它可以使用 package/namespace 分组,使用 hide、show、remove 等命令裁剪成员或元素,还可以用 skinparam 控制输出风格。
PlantUML 代码和图
@startuml
skinparam classAttributeIconSize 0
hide empty members
package "order.domain" {
abstract class AggregateRoot {
+id: String
#raise(event)
}
class Order {
-items: List<OrderItem>
+checkout()
+cancel()
}
class OrderItem {
-productId: String
-quantity: int
}
}
package "payment.domain" {
interface PaymentGateway {
+authorize(orderId, amount): PaymentResult
}
class StripeGateway {
+authorize(orderId, amount): PaymentResult
}
}
AggregateRoot <|-- Order
Order *-- OrderItem
Order ..> PaymentGateway
PaymentGateway <|.. StripeGateway
note right of Order
Public methods are kept visible
for the architecture review.
end note
@enduml
Mermaid 近似表达
classDiagram
namespace order.domain {
class AggregateRoot {
<<Abstract>>
+String id
#raise(event)
}
class Order {
-List~OrderItem~ items
+checkout()
+cancel()
}
class OrderItem {
-String productId
-int quantity
}
}
namespace payment.domain {
class PaymentGateway {
<<Interface>>
+authorize(orderId, amount) PaymentResult
}
class StripeGateway {
+authorize(orderId, amount) PaymentResult
}
}
AggregateRoot <|-- Order
Order *-- OrderItem
Order ..> PaymentGateway
PaymentGateway <|.. StripeGateway
note for Order "Public methods are kept visible\nfor the architecture review."
为什么这个场景更适合 PlantUML?
Mermaid 可以近似表达这张图,但能力边界不同:
- Mermaid 的
namespace可以做基础分组,PlantUML 的 package/namespace 和包样式更适合大型模型。 - Mermaid 可以通过
hideEmptyMembersBox等配置优化空成员框,PlantUML 可以更细地隐藏属性、方法、类、未连接类或带特定标签的元素。 - Mermaid 的
note for足够表达说明文字,PlantUML 的方向注释、浮动注释、链接注释、字段/方法注释更适合复杂评审图。 - Mermaid 的
classDef适合局部样式,PlantUML 的skinparam和 stereotype 样式更适合统一输出规范。
这就是 PlantUML 在类图里的真正优势:不是能不能画类和关系,而是能不能管理一个持续变大的模型视图。
Mermaid 更适合嵌入式说明图
如果你的类图主要放在 README、产品技术说明、轻量 ADR 或在线文档里,Mermaid 的优势很明显:代码短,阅读成本低,和 Markdown 内容贴得近。
Mermaid 代码和图
classDiagram
class DiagramProject {
+String id
+String title
+DiagramType type
+save()
}
class Renderer {
<<Interface>>
+render(source) SvgResult
}
class MermaidRenderer {
+render(source) SvgResult
}
class PlantUmlRenderer {
+render(source) SvgResult
}
DiagramProject --> Renderer : uses
Renderer <|.. MermaidRenderer
Renderer <|.. PlantUmlRenderer
note for Renderer "A renderer converts diagram source into SVG."
这类图的目标不是完整建模,而是让读者快速理解代码结构。对这种“解释一个模块”的场景,Mermaid 的轻量感反而是优点。
类图选择建议
选 Mermaid 写类图,如果这张图的重点是:
- 展示一个中小型领域模型。
- 说明几个类之间的继承、实现、组合和依赖关系。
- 放在 README、Markdown 文档、产品技术说明或轻量设计文档里。
- 读者需要快速看懂结构,而不是审查完整 UML 语义。
- 图的规模可控,不需要频繁生成多个裁剪视图。
选 PlantUML 写类图,如果这张图的重点是:
- 表达更正式的 UML 类图语义。
- 需要直接声明
interface、enum、abstract class、record、dataclass等元素。 - 需要 package、namespace、多种包样式或大型模型分组。
- 需要隐藏属性、隐藏方法、移除元素、展示不同评审视图。
- 需要关联类、字段/方法注释、链接注释或更复杂的说明结构。
- 需要稳定的样式规范,例如统一字体、颜色、stereotype 和输出风格。
常见问题
Mermaid 类图支持继承、组合和聚合吗?
支持。Mermaid 官方类图支持继承、组合、聚合、关联、依赖、实现、实线链接和虚线链接等常见关系,也支持关系两端的基数标注。不要因为图里有继承或组合,就直接判断 Mermaid 不够用。
Mermaid 类图支持接口和枚举吗?
支持表达,但方式更偏 annotation。你可以使用 <<Interface>>、<<Enumeration>> 这类标记说明类的性质。PlantUML 则可以直接使用 interface、enum 等声明元素,语义更显式。
PlantUML 类图一定比 Mermaid 更适合所有项目吗?
不一定。如果你的图只是为了说明几个类的关系,PlantUML 的完整能力可能用不上。Mermaid 更轻、更适合嵌入 Markdown,也更适合快速维护。PlantUML 更适合大型模型、正式 UML、架构评审和需要长期统一输出风格的场景。
只看图形能力,Mermaid 和 PlantUML 类图怎么选?
如果图的重点是“让读者快速理解结构”,Mermaid 通常就够了。如果图的重点是“准确表达 UML 语义并维护多个复杂视图”,PlantUML 更合适。
最终结论:
在类图这一项上,Mermaid 的基础表达能力已经很完整;PlantUML 的优势主要体现在更丰富的 UML 元素、更强的视图裁剪、更成熟的分组和样式控制。轻量说明选 Mermaid,正式建模和复杂架构图选 PlantUML。
你可以在 OnUML 编辑器 中分别使用 Mermaid 和 PlantUML 模式,把上面的示例复制进去对比效果。