PlantUML 完整教程:从入门到精通

什么是 PlantUML

PlantUML 是一个开源工具,允许用户使用简单直观的文本描述来快速创建 UML 图表。它基于纯文本语法,能够生成多种类型的图表,包括时序图、用例图、类图、活动图、组件图、状态图等。

PlantUML 的核心理念是:用代码画图,让图表版本可控

核心特点

  • 文本驱动:使用简单的文本语法描述图表
  • 版本控制友好:纯文本格式可轻松集成到 Git 等版本控制系统
  • 多格式输出:支持 PNG、SVG、PDF、LaTeX 等多种输出格式
  • 跨平台:基于 Java,可在 Windows、Linux、macOS 上运行
  • 集成性强:可集成到各种编辑器、IDE 和文档系统中

为什么选择 PlantUML

传统画图工具的痛点

    1. 版本控制困难:二进制文件难以追踪变更
    1. 协作不便:多人编辑容易冲突
    1. 维护成本高:图表修改繁琐,容易与代码脱节
    1. 格式不统一:不同工具导致风格不一致

PlantUML 的优势

特性 PlantUML 传统图形工具
版本控制 ✅ 完美支持 ❌ 困难
代码审查 ✅ 可以 Code Review ❌ 不可以
自动布局 ✅ 智能布局 ❌ 手动调整
快速修改 ✅ 修改文本即可 ❌ 需要拖拽调整
团队协作 ✅ 易于合并 ❌ 容易冲突
文档集成 ✅ 可嵌入 Markdown ❌ 需要截图

安装与配置

方法一:在线使用

访问 PlantUML 在线编辑器 即可直接使用,无需安装。

方法二:本地安装

前置要求

PlantUML 基于 Java,需要先安装 Java 运行环境:

bash 复制代码
# 检查 Java 版本(需要 Java 8 或更高版本)
java -version

下载 PlantUML

    1. 官方网站 下载 plantuml.jar
    1. 或使用命令下载:
ruby 复制代码
curl -L -o plantuml.jar https://github.com/plantuml/plantuml/releases/download/v1.2023.13/plantuml-1.2023.13.jar

基本使用

bash 复制代码
# 生成 PNG 图片
java -jar plantuml.jar diagram.puml

# 生成 SVG 图片
java -jar plantuml.jar -tsvg diagram.puml

# 监控文件变化自动生成
java -jar plantuml.jar -gui

方法三:编辑器插件

Visual Studio Code

    1. 安装插件:搜索 "PlantUML"
    1. 安装 Graphviz(用于复杂布局):
    csharp 复制代码
    # Windows (使用 Chocolatey)
    choco install graphviz
    
    # macOS
    brew install graphviz
    
    # Ubuntu/Debian
    sudo apt-get install graphviz
    1. 预览快捷键:Alt + D

IntelliJ IDEA

    1. 打开 SettingsPlugins
    1. 搜索 "PlantUML integration"
    1. 安装并重启 IDE

Sublime Text

安装 PlantUML 插件即可。


基础语法

通用规则

所有 PlantUML 图表都遵循以下基本结构:

less 复制代码
@startuml
' 这是注释
' 图表内容写在这里
@enduml

注释

less 复制代码
@startuml
' 单行注释使用单引号

/' 
多行注释
使用 /' 和 '/
'/

@enduml

样式与主题

less 复制代码
@startuml
!theme cerulean-outline
' 其他可用主题:amiga, blueprint, carbon-gray, mars, materia 等

skinparam backgroundColor #EEEBDC
skinparam handwritten true
@enduml

图表类型详解

时序图

时序图用于展示对象之间的交互顺序,是软件设计中最常用的图表之一。

基础示例

less 复制代码
@startuml
' 参与者声明
actor 用户
participant "前端页面" as Frontend
participant "后端API" as Backend
database "数据库" as DB

' 交互流程
用户 -> Frontend: 输入用户名密码
Frontend -> Backend: POST /api/login
Backend -> DB: 查询用户信息
DB --> Backend: 返回用户数据
Backend --> Frontend: 返回 JWT Token
Frontend --> 用户: 登录成功
@enduml

高级特性

less 复制代码
@startuml
title 用户支付流程

actor 用户
participant "前端" as F
participant "订单服务" as O
participant "支付服务" as P
participant "第三方支付" as T
database Redis
database MySQL

用户 -> F: 点击支付
activate F

F -> O: 创建订单
activate O
O -> MySQL: 保存订单
O -> Redis: 缓存订单信息
O --> F: 返回订单号
deactivate O

F -> P: 发起支付请求
activate P
P -> T: 调用支付接口
activate T

alt 支付成功
    T --> P: 支付成功回调
    P -> O: 更新订单状态
    P --> F: 支付成功
    F --> 用户: 显示支付成功
else 支付失败
    T --> P: 支付失败
    P --> F: 支付失败
    F --> 用户: 显示失败原因
end

deactivate T
deactivate P
deactivate F
@enduml

关键语法说明

  • -> :实线箭头
  • --> :虚线箭头(返回)
  • activate / deactivate:激活/停用生命线
  • alt / else / end:条件分支
  • loop / end:循环
  • par / end:并行处理

用例图

用例图描述系统功能和用户的交互关系。

scss 复制代码
@startuml
left to right direction
skinparam packageStyle rectangle

actor 顾客
actor 收银员
actor 管理员

rectangle 电商系统 {
  顾客 -- (浏览商品)
  顾客 -- (添加购物车)
  顾客 -- (下单支付)
  顾客 -- (查看订单)
  
  收银员 -- (处理订单)
  收银员 -- (处理退款)
  
  管理员 -- (管理商品)
  管理员 -- (查看报表)
  管理员 -- (管理用户)
  
  (下单支付) .> (添加购物车) : <<include>>
  (处理退款) .> (处理订单) : <<extend>>
}
@enduml

关键元素

  • actor:参与者
  • (用例名):用例
  • --:关联关系
  • .>:依赖关系(include、extend)

类图

类图是面向对象设计的核心图表,展示类的结构和类之间的关系。

vbnet 复制代码
@startuml
title 电商系统类图

abstract class User {
  # id: Long
  # username: String
  # email: String
  # createTime: Date
  --
  + login(): boolean
  + logout(): void
  # validateEmail(): boolean
}

class Customer extends User {
  - address: String
  - phone: String
  --
  + placeOrder(Order): void
  + viewOrderHistory(): List<Order>
}

class Admin extends User {
  - role: String
  --
  + manageProducts(): void
  + viewReports(): void
}

class Product {
  - id: Long
  - name: String
  - price: BigDecimal
  - stock: Integer
  - category: Category
  --
  + updateStock(int): void
  + getDiscountPrice(): BigDecimal
}

class Order {
  - orderId: String
  - customer: Customer
  - orderDate: Date
  - status: OrderStatus
  - totalAmount: BigDecimal
  --
  + calculateTotal(): BigDecimal
  + cancel(): void
  + pay(): boolean
}

class OrderItem {
  - product: Product
  - quantity: Integer
  - price: BigDecimal
  --
  + getSubTotal(): BigDecimal
}

enum OrderStatus {
  PENDING
  PAID
  SHIPPED
  COMPLETED
  CANCELLED
}

class Category {
  - id: Long
  - name: String
  - parentCategory: Category
}

' 关系定义
Customer "1" -- "*" Order : places >
Order "1" *-- "*" OrderItem : contains
OrderItem "*" --> "1" Product : refers to
Product "*" --> "1" Category : belongs to
Order --> OrderStatus : has

note right of Order
  订单创建后24小时内
  未支付将自动取消
end note

note top of Product
  商品价格支持促销折扣
  库存不足时无法下单
end note

@enduml

关系类型

  • --|>:泛化(继承)
  • ..|>:实现(接口)
  • -->:关联
  • *--:组合
  • o--:聚合
  • ..>:依赖

可见性修饰符

  • -:private
  • #:protected
  • ~:package
  • +:public

活动图

活动图描述业务流程或算法逻辑。

css 复制代码
@startuml
title 用户注册流程

start

:用户访问注册页面;

:填写注册信息;
note right
  包括:
  * 用户名
  * 邮箱
  * 密码
end note

:提交注册表单;

if (表单验证通过?) then (是)
  :保存用户信息;
  
  fork
    :发送欢迎邮件;
  fork again
    :发送短信通知;
  fork again
    :记录注册日志;
  end fork
  
  :跳转到登录页面;
  :显示注册成功提示;
  
else (否)
  :显示错误信息;
  
  if (重试次数 < 3?) then (是)
    :返回注册页面;
    :保留已填写信息;
  else (否)
    :锁定注册;
    :显示联系客服提示;
    stop
  endif
  
endif

stop

@enduml

常用元素

  • start / stop:开始/结束
  • :活动;:活动节点
  • if/then/else/endif:条件判断
  • while/endwhile:循环
  • fork/fork again/end fork:并行处理
  • partition:泳道分区

带泳道的活动图

css 复制代码
@startuml
|用户|
start
:提交请假申请;

|直属主管|
:审批申请;

if (是否批准?) then (批准)
  |HR部门|
  :记录请假信息;
  :更新考勤系统;
  
  |用户|
  :收到批准通知;
  stop
else (拒绝)
  |用户|
  :收到拒绝通知;
  :查看拒绝原因;
  stop
endif

@enduml

组件图

组件图展示系统的物理组件及其依赖关系。

less 复制代码
@startuml
title 微服务架构组件图

package "前端层" {
  [Web前端] as Web
  [移动端APP] as Mobile
}

package "网关层" {
  [API Gateway] as Gateway
}

package "服务层" {
  [用户服务] as UserService
  [订单服务] as OrderService
  [商品服务] as ProductService
  [支付服务] as PaymentService
}

package "基础设施层" {
  [认证中心] as Auth
  [配置中心] as Config
  [服务注册中心] as Registry
}

database "MySQL集群" {
  [用户数据库]
  [订单数据库]
  [商品数据库]
}

cloud "第三方服务" {
  [微信支付]
  [阿里云OSS]
}

Web --> Gateway
Mobile --> Gateway

Gateway --> UserService
Gateway --> OrderService
Gateway --> ProductService

OrderService --> PaymentService
PaymentService --> [微信支付]

UserService --> Auth
OrderService --> Auth

UserService --> Registry
OrderService --> Registry
ProductService --> Registry
PaymentService --> Registry

UserService --> [用户数据库]
OrderService --> [订单数据库]
ProductService --> [商品数据库]

@enduml

状态图

状态图描述对象的生命周期和状态转换。

lua 复制代码
@startuml
title 订单状态流转图

[*] --> 待支付 : 创建订单

待支付 --> 已支付 : 支付成功
待支付 --> 已取消 : 超时/手动取消
待支付 --> 已取消 : 库存不足

已支付 --> 待发货 : 进入发货队列
已支付 --> 退款中 : 申请退款

待发货 --> 已发货 : 发货
待发货 --> 退款中 : 申请退款

已发货 --> 已签收 : 确认收货
已发货 --> 退款中 : 申请退货

已签收 --> 已完成 : 系统自动确认
已签收 --> 售后中 : 申请售后

售后中 --> 已完成 : 售后完成

退款中 --> 已退款 : 退款成功
退款中 --> 已支付 : 退款失败

已取消 --> [*]
已完成 --> [*]
已退款 --> [*]

待支付 : entry / 发送支付通知
待支付 : exit / 释放库存锁定

已发货 : do / 物流跟踪
已发货 : 预计3-5天送达

@enduml

状态语法

  • entry /:进入状态时执行
  • exit /:离开状态时执行
  • do /:在状态中持续执行

对象图

对象图展示特定时刻对象实例及其关系。

kotlin 复制代码
@startuml
title 订单对象实例图

object 订单001 {
  订单号 = "ORD20231015001"
  订单日期 = "2023-10-15"
  状态 = "已支付"
  总金额 = 1299.00
}

object 客户张三 {
  客户ID = "CUST001"
  姓名 = "张三"
  会员等级 = "金卡"
}

object 商品iPhone {
  商品ID = "PROD001"
  商品名称 = "iPhone 15"
  价格 = 5999.00
}

object 商品保护壳 {
  商品ID = "PROD002"
  商品名称 = "iPhone保护壳"
  价格 = 99.00
}

object 订单明细1 {
  数量 = 1
  单价 = 5999.00
}

object 订单明细2 {
  数量 = 2
  单价 = 99.00
}

客户张三 -- 订单001
订单001 *-- 订单明细1
订单001 *-- 订单明细2
订单明细1 --> 商品iPhone
订单明细2 --> 商品保护壳

@enduml

部署图

部署图展示系统的物理部署架构。

rust 复制代码
@startuml
title 生产环境部署图

node "负载均衡器" as LB {
  [Nginx] as nginx
}

node "应用服务器集群" {
  node "服务器1" as APP1 {
    [应用实例1] as app1
  }
  
  node "服务器2" as APP2 {
    [应用实例2] as app2
  }
  
  node "服务器3" as APP3 {
    [应用实例3] as app3
  }
}

node "数据库服务器" as DBMS {
  database "MySQL主库" as DBMaster
  database "MySQL从库1" as DBSlave1
  database "MySQL从库2" as DBSlave2
}

node "缓存服务器" as CacheServer {
  database "Redis集群" as redis
}

node "文件存储" as Storage {
  [MinIO] as minio
}

cloud "CDN" as cdn

nginx --> app1
nginx --> app2
nginx --> app3

app1 --> DBMaster
app2 --> DBMaster
app3 --> DBMaster

app1 --> DBSlave1
app2 --> DBSlave2

app1 --> redis
app2 --> redis
app3 --> redis

app1 --> minio
app2 --> minio
app3 --> minio

DBMaster -down-> DBSlave1 : 主从复制
DBMaster -down-> DBSlave2 : 主从复制

minio -up-> cdn : 静态资源分发

@enduml

时间图

时间图展示对象状态随时间的变化。

less 复制代码
@startuml
robust "Web服务器" as WEB
robust "应用服务器" as APP
robust "数据库服务器" as DB

@0
WEB is 空闲
APP is 空闲
DB is 空闲

@100
WEB is 处理请求
@200
APP is 查询数据
@300
DB is 执行SQL
@400
DB is 返回结果
@500
APP is 处理数据
@600
WEB is 返回响应
@700
WEB is 空闲
APP is 空闲
DB is 空闲

@enduml

甘特图

甘特图用于项目进度管理。

ini 复制代码
@startgantt
title 项目开发计划

Project starts 2023-10-01

[需求分析] lasts 5 days
[UI设计] lasts 7 days
[原型制作] lasts 5 days

[需求分析] -> [UI设计]
[UI设计] -> [原型制作]

[前端开发] lasts 15 days
[后端开发] lasts 20 days
[数据库设计] lasts 5 days

[原型制作] -> [前端开发]
[需求分析] -> [后端开发]
[需求分析] -> [数据库设计]
[数据库设计] -> [后端开发]

[前端测试] lasts 5 days
[后端测试] lasts 5 days
[前端开发] -> [前端测试]
[后端开发] -> [后端测试]

[集成测试] lasts 7 days
[前端测试] -> [集成测试]
[后端测试] -> [集成测试]

[上线部署] lasts 2 days
[集成测试] -> [上线部署]

[需求分析] is colored in Fuchsia/FireBrick
[UI设计] is colored in GreenYellow/Green
[前端开发] is colored in Cyan/Blue
[后端开发] is colored in Cyan/Blue

@endgantt

思维导图

PlantUML 也支持思维导图(Mind Map)。

markdown 复制代码
@startmindmap
title 学习 PlantUML

* PlantUML
** 基础知识
*** 安装配置
*** 基本语法
*** 编辑器集成
** 图表类型
*** 结构图
**** 类图
**** 组件图
**** 部署图
**** 对象图
*** 行为图
**** 用例图
**** 时序图
**** 活动图
**** 状态图
*** 其他
**** 甘特图
**** 思维导图
**** 架构图
** 高级特性
*** 样式定制
*** 主题应用
*** 宏定义
*** 包含文件
** 实践应用
*** 技术文档
*** 项目设计
*** 代码注释
*** 团队协作

@endmindmap

高级特性

1. 样式定制

typescript 复制代码
@startuml
skinparam class {
  BackgroundColor PaleGreen
  ArrowColor SeaGreen
  BorderColor SpringGreen
  FontName Arial
  FontSize 14
}

skinparam stereotypeCBackgroundColor YellowGreen

class Example {
  + field: String
  + method(): void
}
@enduml

2. 使用变量和宏

less 复制代码
@startuml
!define ENTITY(name) class name << (E,#FFAAAA) >>
!define SERVICE(name) class name << (S,#AAFFAA) >>

ENTITY(User)
ENTITY(Order)
SERVICE(UserService)
SERVICE(OrderService)

User --> UserService
Order --> OrderService
@enduml

3. 包含外部文件

less 复制代码
@startuml
!include common-styles.puml
!include entities.puml

' 使用已定义的样式和类
@enduml

4. 使用标准库

less 复制代码
@startuml
!include <aws/common>
!include <aws/Storage/AmazonS3/AmazonS3>
!include <aws/Compute/AmazonEC2/AmazonEC2>

AmazonEC2(ec2, "应用服务器", "")
AmazonS3(s3, "文件存储", "")

ec2 --> s3
@enduml

5. 预处理功能

less 复制代码
@startuml
!$company = "我的公司"
!$debug = %true()

!if $debug
  title $company + " - 开发环境"
!else
  title $company + " - 生产环境"
!endif

@enduml

6. 图表布局控制

less 复制代码
@startuml
' 从左到右布局
left to right direction

' 隐藏某些元素
hide empty members
hide circle

' 页面设置
scale 1.5
skinparam dpi 300

@enduml

实际应用场景

1. 技术文档编写

在 Markdown 文档中嵌入 PlantUML:

perl 复制代码
# 系统架构设计

## 时序图

```plantuml
@startuml
Alice -> Bob: 你好
Bob --> Alice: 你好
@enduml
```

2. 代码注释

在代码中使用 PlantUML 描述逻辑:

markdown 复制代码
/**
 * 用户登录流程
 * 
 * @startuml
 * actor User
 * User -> LoginController: login(username, password)
 * LoginController -> UserService: authenticate()
 * UserService -> Database: queryUser()
 * Database --> UserService: User
 * UserService --> LoginController: Token
 * LoginController --> User: Success
 * @enduml
 */
public void login(String username, String password) {
    // 实现代码
}

3. Git 版本控制

bash 复制代码
# 将 .puml 文件加入版本控制
git add docs/diagrams/*.puml

# 在 Pull Request 中可以看到图表的文本差异
git diff docs/diagrams/architecture.puml

4. CI/CD 集成

在 GitLab CI 或 GitHub Actions 中自动生成图表:

yaml 复制代码
# .github/workflows/generate-diagrams.yml
name: Generate PlantUML Diagrams

on: [push]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Generate PlantUML
        uses: grassedge/generate-plantuml-action@v1.5
        with:
          path: docs/diagrams
          message: "Auto-generated diagrams"
      - name: Commit changes
        run: |
          git config user.name github-actions
          git config user.email github-actions@github.com
          git add .
          git commit -m "Update diagrams" || exit 0
          git push

5. Wiki 和 Confluence 集成

许多 Wiki 系统支持 PlantUML 插件,可以直接渲染图表。


最佳实践

1. 文件组织

css 复制代码
project/
├── docs/
│   ├── diagrams/
│   │   ├── architecture/
│   │   │   ├── overview.puml
│   │   │   └── components.puml
│   │   ├── sequence/
│   │   │   ├── login-flow.puml
│   │   │   └── payment-flow.puml
│   │   └── class/
│   │       ├── domain-model.puml
│   │       └── service-layer.puml
│   └── README.md
└── styles/
    └── common.puml

2. 命名规范

  • 文件名:使用小写字母,单词用连字符分隔

    • user-login-sequence.puml
    • order-service-class-diagram.puml
  • 图表标题:清晰描述图表内容

    复制代码
    title 用户登录时序图 - v1.2
  • 元素命名:使用有意义的名称

    kotlin 复制代码
    class UserService
    participant "订单服务" as OrderService

3. 注释和文档

less 复制代码
@startuml
title 订单处理流程

' ========================================
' 作者:张三
' 日期:2023-10-15
' 版本:1.0
' 描述:展示从下单到支付的完整流程
' ========================================

note right of Order
  订单创建后需要在30分钟内完成支付
  否则将自动取消并释放库存
end note

@enduml

4. 保持简洁

  • • 避免在一个图表中包含过多信息
  • • 复杂系统应拆分为多个图表
  • • 每个图表聚焦一个核心主题

5. 使用样式一致性

创建共享样式文件:

scss 复制代码
' common-styles.puml
@startuml
skinparam backgroundColor #FFFFFF
skinparam classBackgroundColor #E8F5E9
skinparam classBorderColor #4CAF50
skinparam classFontSize 12
skinparam classFontName Microsoft YaHei

skinparam sequenceArrowColor #2196F3
skinparam sequenceLifeLineBorderColor #1976D2

skinparam activityStartColor #4CAF50
skinparam activityEndColor #F44336
skinparam activityBackgroundColor #FFF9C4
skinparam activityBorderColor #FBC02D

@enduml

在其他文件中引用:

less 复制代码
@startuml
!include ../styles/common-styles.puml

' 你的图表内容
@enduml

6. 版本管理

在图表中记录版本信息:

less 复制代码
@startuml
header
  版本: 2.1
  修改日期: 2023-10-15
  修改人: 李四
end header

footer Page %page% of %lastpage%

@enduml

7. 自动化生成

创建脚本批量生成图片:

bash 复制代码
#!/bin/bash
# generate-all.sh

PUML_DIR="./diagrams"
OUTPUT_DIR="./output"

mkdir -p $OUTPUT_DIR

for file in $PUML_DIR/**/*.puml; do
  echo "Processing $file..."
  java -jar plantuml.jar -o $OUTPUT_DIR -tsvg $file
done

echo "All diagrams generated!"

常见问题与解决方案

1. 中文显示问题

如果中文显示为方框,需要配置字体:

less 复制代码
@startuml
skinparam defaultFontName Microsoft YaHei
' 或者
skinparam defaultFontName SimHei
@enduml

2. 图表太大

less 复制代码
@startuml
scale 0.8
' 或者
scale 800 width
' 或者
scale 600 height
@enduml

3. 箭头方向控制

less 复制代码
@startuml
' 强制从左到右
A -right-> B

' 强制从上到下
C -down-> D

' 强制从右到左
E -left-> F

' 强制从下到上
G -up-> H
@enduml

4. 隐藏不必要的元素

less 复制代码
@startuml
hide empty members
hide circle
hide stereotype
@enduml

总结

PlantUML 是一个强大且灵活的工具,特别适合:

版本控制 :纯文本格式,完美集成 Git

快速迭代 :修改文本即可,无需拖拽

团队协作 :易于代码审查和合并

文档同步 :图表与代码放在一起,不易脱节

自动化:可集成到 CI/CD 流程

虽然 PlantUML 需要学习一定的语法,但其带来的效率提升和版本控制便利性远超传统的图形化工具。对于需要频繁更新和维护技术文档的团队来说,PlantUML 是一个理想的选择。


参考资源


附录:常用命令速查表

图表类型 开始标记 结束标记
时序图 @startuml @enduml
用例图 @startuml @enduml
类图 @startuml @enduml
活动图 @startuml @enduml
状态图 @startuml @enduml
甘特图 @startgantt @endgantt
思维导图 @startmindmap @endmindmap

箭头类型

符号 说明
-> 实线箭头
--> 虚线箭头
->> 实线双箭头
-->> 虚线双箭头
- 半箭头

关系类型(类图)

符号 关系
`< --`
`< ...`
*-- 组合
o-- 聚合
--> 关联
..> 依赖

相关推荐
东方掌管牛马的神2 小时前
oh-my-zsh 配置与使用技巧
前端
你的人类朋友2 小时前
HTTP请求结合HMAC增加安全性
前端·后端·安全
武子康2 小时前
大数据-113 Flink 源算子详解:非并行源(Non-Parallel Source)的原理与应用场景
大数据·后端·flink
QZQ541882 小时前
高性能现代CPP--表达式模板(expression templates)
后端
aidingni8882 小时前
掌握 TCJS 游戏摄像系统:打造动态影院级体验
前端·javascript
有梦想的攻城狮3 小时前
从0开始学vue:npm命令详解
前端·vue.js·npm
我是日安3 小时前
从零到一打造 Vue3 响应式系统 Day 23 - Watch:基础实现
前端·javascript·vue.js
莹Innsane3 小时前
使用 VictoriaLogs 存储和查询服务器日志
后端
FogLetter3 小时前
TypeScript 泛型:让类型也拥有“函数式”超能力
前端·typescript