Mermaid vs PlantUML 类图:正式 UML 为什么默认选 PlantUML
本文只比较类图表达和长期维护能力,PlantUML 更强,应作为正式 UML 类图的默认选择。 官方资料核验于 2026-07-22;整体工具差异请看系列总览。
Mermaid 足以说明常见领域对象、成员和关系;但正式设计资产通常还要承载关联类、明确声明元素、可裁剪视图、细粒度注释和稳定的样式规则。这些场景下,PlantUML 的官方语法覆盖得更完整。
核心结论
本文依据以下一手资料:
Mermaid vs PlantUML 类图核心差异
| 对比点 | Mermaid | PlantUML | 选择建议 |
|---|---|---|---|
| 类、属性、方法 | 支持 | 支持 | 两者都可以 |
| 可见性 | 支持 +、-、#、~ | 支持 +、-、#、~ | 两者都可以 |
| 静态/抽象成员 | 支持 $ 和 * 标记 | 支持 {static}、{abstract} 等更显式写法 | 正式 UML 图 PlantUML 更清楚 |
| 继承/实现/组合/聚合/依赖 | 支持常见关系 | 支持常见关系 | 两者都可以 |
| 基数 | 支持关系两端标注 | 支持关系两端标注 | 两者都可以 |
| 泛型 | 支持 ~T~,但复杂泛型有限制 | 支持泛型表达 | 复杂类型模型 PlantUML 更合适 |
| 接口/枚举/抽象类 | 通过 annotation 表达 | 有 interface、enum、abstract class 等声明元素 | PlantUML 语义更显式 |
| 包和命名空间 | 官网 11.15.0+ 支持嵌套 namespace;项目 11.6.0 不具备此版本能力 | 支持 package、namespace 和多种包样式 | 版本与长期模型都要单独判断 |
| 隐藏成员和裁剪视图 | 官方类图页未提供对应裁剪命令 | 支持 hide、show、remove、restore、按标签裁剪 | 设计评审 PlantUML 更合适 |
| 注释 | 支持 note 和 note for | 支持方向注释、浮动注释、链接注释、字段/方法注释 | PlantUML 注释能力更细 |
| 关联类 | 不突出 | 支持 association class | 需要严格 UML 语义时选 PlantUML |
| 样式控制 | 支持 classDef、CSS class、主题配置 | 支持 skinparam、颜色、stereotype 样式等 | 统一图形规范 PlantUML 更合适 |
先给一句话结论:
Mermaid 类图适合把结构讲清楚;PlantUML 类图适合把结构、语义、裁剪视图和输出规范一起控制住。
Mermaid 能覆盖常见类模型吗?
能。Mermaid 官方类图文档列出 8 种关系,并支持 +、-、#、~ 可见性、泛型、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 已经可以把结构讲清楚。它不是只能画“几个方框加几条线”;类成员、接口标记、枚举标记、组合关系和基数都能表达。
为什么正式 UML 类图更适合 PlantUML?
PlantUML 官方类图语法直接提供 class、interface、enum、abstract class、annotation、entity、record、dataclass、protocol 等声明元素。Mermaid 可用 <<Interface>>、<<Enumeration>> 表示性质,但 PlantUML 的元素类型在源码和图上都更显式。
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 的 hide/show/remove/restore 与按标签操作可裁剪成员或类,让同一源模型服务多个读者;这是长期维护层面的直接语法优势。
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 官网 11.15.0+ 的
namespace已可嵌套(Mermaid Class diagrams);这里需要区分官网能力与本项目锁定的 11.6.0。 - PlantUML 可隐藏或恢复属性、方法、类及标签视图(PlantUML Class Diagram syntax and features);Mermaid 官方类图文档没有列出同类裁剪命令。
- PlantUML 支持为类、字段、方法和关系添加注释,字段或方法注释仅限左右位置,且受
namespaceSeparator限制(PlantUML Class Diagram syntax and features)。 - PlantUML 提供关联类专用写法;截至核验日,Mermaid 官方类图页未列出对应专用语法(PlantUML Class Diagram syntax and features,Mermaid Class diagrams)。
样式治理与架构分层怎么做?
官网 Mermaid 11.15.0 起支持显示标签和嵌套 namespace,不能再把 namespace 写成 PlantUML 独占能力。跨多张图的规范则可用 PlantUML 的 skinparam、stereotype 样式和包样式集中治理;类图与系统边界的配合请参见软件架构图对比。
关联类的专用语法
关联类把一条关系本身当成需要属性或行为的建模元素。PlantUML 官方类图文档提供相应写法;截至核验日,Mermaid 官方类图页未列出对应专用语法。是否能用普通类近似,不应被误写为已有专用 UML 表达。
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."
这类图仍能清楚解释一个模块。是否切换到 PlantUML,取决于是否需要正式声明、关联类、裁剪视图和统一样式,而不是图中是否出现继承线。
类图选择结论
选 Mermaid 写类图,如果这张图的重点是:
- 展示一个中小型领域模型。
- 说明几个类之间的继承、实现、组合和依赖关系。
- 读者需要快速看懂结构,而不是审查完整 UML 语义。
- 图的规模可控,不需要频繁生成多个裁剪视图。
选 PlantUML 写类图,如果这张图的重点是:
- 表达更正式的 UML 类图语义。
- 需要直接声明
interface、enum、abstract class、record、dataclass等元素。 - 需要 package、namespace、多种包样式或大型模型分组。
- 需要隐藏属性、隐藏方法、移除元素、展示不同评审视图。
- 需要关联类、字段/方法注释、链接注释或更复杂的说明结构。
- 需要稳定的样式规范,例如统一字体、颜色、stereotype 和输出风格。
类图选型有哪些常见问题?
Mermaid 类图支持继承、组合和聚合吗?
支持。Mermaid 官方类图支持继承、组合、聚合、关联、依赖、实现、实线链接和虚线链接等常见关系,也支持关系两端的基数标注。不要因为图里有继承或组合,就直接判断 Mermaid 不够用。
Mermaid 类图支持接口和枚举吗?
支持表达,但方式更偏 annotation。你可以使用 <<Interface>>、<<Enumeration>> 这类标记说明类的性质。PlantUML 则可以直接使用 interface、enum 等声明元素,语义更显式。
Mermaid 的嵌套 namespace 仍然不能用吗?
不能这样判断。Mermaid 官网自 11.15.0 起已文档化嵌套 namespace;本项目锁定 11.6.0,因此不能把该新语法直接用于当前版本。PlantUML 的优势应放在关联类、声明元素、裁剪命令、细粒度注释和样式治理。
只看图形能力,Mermaid 和 PlantUML 类图怎么选?
如果图的重点是“让读者快速理解结构”,Mermaid 通常就够了。如果图的重点是“准确表达 UML 语义并维护多个复杂视图”,PlantUML 更合适。
最终结论:
只比较类图表达和长期维护能力,PlantUML 更强,应作为正式 UML 类图的默认选择。 Mermaid 仍是常见对象模型的合格表达方式;当设计需要长期归档和多视图维护时,PlantUML 的语法优势更直接。