PlantUML时序图完全指南

6,909 阅读9分钟

开源网站:github.com/plantuml/pl…

官方教学文档:plantuml.com/zh/sequence…

PlantUML 是一个开源工具,用于创建 UML(统一建模语言)图表。它让用户能够通过简单的文本描述来生成图表,而不是使用传统的图形编辑器。这种方法可以更快速、更有效地创建和维护图表。

PlantUML 支持多种 UML 图表类型,包括类图、序列图、用例图、活动图、组件图、状态图等

一、基本例子

@startuml
participant Alice as A
participant Bob as B
A->B: Hello Alice!
B-->A: Hi!
@enduml
'单行注释
/'多行注释'/
image-20231017092151677

二、基本语法

1、方向

  • -> 实线
  • --> 虚线

也存在 <- 与 <--,增加其可令可读性增高,不过较少使用。

默认情况下,线条是平行的,我们可以使用 ->(倾斜度) 来使箭头倾斜:

@startuml
Alice ->(10) Bob : hello
Bob ->(10) Alice : hello
@enduml

image-20231017162805382

默认情况下,箭头是以先后顺序依次向下递增,我们可以开启 PlantUML 的允许平齐配置,然后使用 & 使得部分箭头平齐:

@startuml
!pragma teoz true
Alice ->(10) Bob : hello
Bob -> Alice : hello
& Clary -> Bob: hello
@enduml

image-20231017163203401

2、参与者

在 PlantUML 中有多种角色可以表示,角色的声明顺序默认是其显示顺序

  • participant:普通参与者
  • actor:角色
  • boundary:边界
  • control:控制
  • entity:实体
  • database:数据库
  • collection:集合
  • queue:队列
@startuml
participant Participant as Foo
actor       Actor       as Foo1
boundary    Boundary    as Foo2
control     Control     as Foo3
entity      Entity      as Foo4
database    Database    as Foo5
collections Collections as Foo6
queue       Queue       as Foo7
Foo -> Foo1 : To actor
Foo -> Foo2 : To boundary
Foo -> Foo3 : To control
Foo -> Foo4 : To entity
Foo -> Foo5 : To database
Foo -> Foo6 : To collections
Foo -> Foo7: To queue
@enduml

image-20231017173717077

我们可以使用 as 关键字重命名参与者,语法格式为:

participant Alice as A

PlantUML 默认显示所有参与者,我们可以声明孤立未参与的参与者:

@startuml
hide unlinked
participant Alice
participant Bob
participant Carol

Alice -> Bob : hello
@enduml

image-20231017162523014

order 关键字可以调整参与者的顺序,如:

'order 表示其排序的顺序。值越小,排序越靠前
actor Alice as A order 20
queue Bob as B   order 10

我们也可以修改参与者的背景色,如:

actor Alice as A #RED
queue Bob as B   #000
image-20231017094032396

多行定义参与者:

@startuml
' 原写法:participant Alice as A 
participant A [
    =Alice
    ---
    "计划"
]
participant Bob as B
A->B: Hello Alice!
B-->A: Hi!
@enduml
image-20231017094838492

当定义的数据中存在“特殊”字符时,使用双引号包裹"",可以使用 \n 换行转义符:

@startuml
participant "Alice \n---\n'Home" as A
participant Bob as B
A->B: Hello Alice!
B-->A: Hi!
@enduml
image-20231017095231478

自己给自己发消息:

B->B: hello
image-20231017095426443

3、skinparam初阶

改变图表样式和外观的选项,注意是 skin - param,而不是 skip - param

文本对齐:sequenceMessageAlign,后接参数 left、right 或 center

@startuml
skinparam SequenceMessageAlignment right
A->B: Hello Alice!
B-->A: Hi!
@enduml
image-20231017095709197

4、箭头样式

  • -xx->x-xx->o:表示丢失的信息
  • --/:只拥有箭头的上部分或下部分
  • ->>-\:拥有一个薄的箭头样式
  • --:点状箭头样式
  • -o:箭头末端会添加 o
  • <->:双向箭头
  • -[#000]>:修改箭头颜色(注意颜色在中间)
@startuml
participant "Alice" as A
participant Bob as B
participant Clary as C
A-> B: Hello
A->>B: Hello
B-x C: Hello
A x->B: Hello
B x-x C: Hello
B x->o C: Hello
A-\ B: Hello
A-\ B: Hello
B<->C: Hello
B->o C: Hello
A-[#red]> B: Hello
@enduml

image-20231017164127257

5、序号

我们可以使用 autonumber 对消息进行自动编号

@startuml
participant "Alice" as A
participant Bob as B
participant Clary as C
autonumber
A-> B: Hello
A->>B: Hello
B-x C: Hello
@enduml
image-20231017105849398
  • autonumber 数字:指定开始的初始序号
  • autonumber "<font color=red><b>[<u>0</u>]":指定数字格式,格式是由 Java 的DecimalFormat类实现的,(0 表示数字;# 也表示数字,但默认为0)。
  • autonumber stopautonumber resume:暂停、恢复计数
  • autonumber 1.1.1:使用分隔符定义数字格式,如 .,;: 等,最后一位数字会自动递增。要增加第一个数字,使用 autonumber inc A,第二个则为 B,以此类推。另外每次调用都会刷新比它等级更低的数值,默认为1。
  • %autonumber%:使用 autonumber 变量的值。
@startuml
participant "Alice" as A
participant Bob as B
participant Clary as C
autonumber
A-> B: Hello
A->>B: Hello
autonumber
B-x C: Hello
autonumber 10
A->B: Hi
autonumber "<font color=red><b>[<u>0</u>]"
A-> B: Hello, my number is: %autonumber%
A->>B: Hello
autonumber 1.1.1
B-> C: Hello
B->>C: Hello
autonumber inc B
B-> C: Hello
B->>C: Hello
@enduml
image-20231017142101721

6、页面配置

  • 页面标题/页眉/页脚,其中标题支持 creole 格式
  • 新页面:newpage,可以同时携带上新标题
@startuml
title "日常--对话--"
header "Page Header"
footer "Page footer %page% of %lastpage%"
autonumber
A-> B: Hello
A->>C: Hello
newpage 日常对话
B->>C: Hello
@enduml

image-20231017172719123

image-20231017151719765

我们也可以使用 hide footbox 显式声明移除页脚(脚注)

@startuml

hide footbox
title Footer removed

Alice -> Bob: Authentication Request
Bob --> Alice: Authentication Response

@enduml

7、分组

我们可以通过以下关键词来组合消息,分组可以嵌套、关键词 ==end== 结束分组:

  • alt/else:用于条件执行,如果条件满足则执行 alt 块中的内容,否则 else
  • opt:optional,可选的选项,只有当某个条件满足时才会被触发
  • loop:循环执行块
  • par:parallel,并行执行块
  • break:中断循环或其他结构
  • critical:关键块,强调某个操作的重要性
  • group:创建一个带有命名的分组
  • ref:引用

我们通过左边顶端显示的英文信息,判断该组合框里代表什么消息类型,也可以为分组的标题框与内容框着色。

@startuml
A -> B: hello
alt#Gold #Lightblue is sunny
    B->A: I will go out
else #Pink is rainy
    B->A: I will stay home
end
@enduml

image-20231017162302352

@startuml
A -> B: hello
opt weekend
    B->A: Let's Go!
end
@enduml
image-20231017152639043
@startuml
A -> B: hello
loop 3 times
    B->A: Let's Go!
end
@enduml
image-20231017152707111
@startuml
par
    A->B: Hello
    B->C: Hello
end
@enduml
image-20231017152831910

注意:break 需要 end 对应,中间可插入其他操作。

@startuml
Alice -> Bob : start checking weather
loop
  Bob -> WeatherAPI : check weather
  WeatherAPI --> Bob : weather status
  alt rain
    Bob -> Alice : It's raining, staying at home
    break count >= 5
    Bob -> Alice : Bye!
    end
  else no rain
    Bob -> Alice : It's sunny, going out
  end
end
@enduml
image-20231017154306444
@startuml
A->B: Hello
critical 关键信息
    B->A: Hi
end
@enduml
image-20231017154553021
@startuml
A->B: Hello
group MyGroup [我的群组]
    B->A: Hi
end
@enduml
image-20231017154731195
@startuml
participant Alice
actor Bob

ref over Alice, Bob : init

Alice -> Bob : hello

ref over Bob
  This can be on
  several lines
end ref
@enduml

image-20231017161304806

8、备注信息

使用关键字 note leftnote right,然后在后面加上「对象」和「信息」。当需要多行备注时,可以使用 end note 结束备注。

可以使用 note left 对象note left of 对象note over 对象 来在对应的地方释放备注。也可以在使用的过程中更改注释卡片的颜色,甚至改变形状

  • hnote:hexagonal 六边形
  • rnote:rectangle 正方形
@startuml
    A->B: Hello
    B->C: Hello
' 单行信息
note over B: Hello
' 多行信息
hnote left A #aqua
This is
multi paragraph
end note
    A->C: Hello
@enduml

image-20231017155601327

如果想要在同一级对齐多个备注,使用 /

@startuml
    A->B: Hello
    B->C: Hello
' 单行信息
note over B: Hello
' 多行信息
/ hnote left A #aqua
This is
multi paragraph
end note
    A->C: Hello
@enduml

image-20231017160324362

多行文本支持 Creole 和 HTML:

@startuml
    A->B: Hello
    B->C: Hello
' 多行信息
/ hnote left A #aqua
This is
**bold**
//italics//
""monospaced""
msg --stroked--
__underline__
~~waved~~
end note
    A->C: Hello
@enduml
image-20231017160919018

注意,-- -- 需要前面带有其他多余字符时才生效,否则不符合预期

--stroked--

image-20231017161050491

可以通过 note across 便捷的覆盖全部参与者

@startuml
    A->B: Hello
    B->C: Hello
note across: Hello
@enduml

image-20231017160131600

9、分隔符

== 关键字

@startuml
participant Alice
participant Bob
== 初始化 ==
Alice -> Bob : hello
Bob -> Alice : hello
== 重复 ==
Alice -> Bob : hello
Bob -> Alice : hello
@enduml

image-20231017161418708

10、延迟

表示“延迟” ...,间距会变大,可在某间隔处多次使用。

@startuml
participant Alice
participant Bob
Alice -> Bob : hello
Alice -> Bob : hello
...
Bob -> Alice : hello
@enduml

image-20231017161547767

另外使用 |||(空间)也可以表示出相似的效果,但是 |||有新写法 ||像素数||

Alice -> Bob : hello
||50||
Bob -> Alice : hello

11、生命线

在 PlantUML 顺序图中,关键字 activatedeactivate 用于表示参与者的活动状态。当一个参与者被激活时,其生命线会显示为一个较宽的矩形。这通常表示参与者正在执行某个操作或处理某个任务。当参与者变为非激活状态时,生命线会恢复为正常宽度。

关键字 destroy 用于表示参与者的生命周期结束。当一个参与者被销毁时,其生命线会显示为一个带有❌的矩形。另外,生命线条可以添加颜色。

@startuml
participant "Object A" as A
participant "Object B" as B
A->B: Request
activate B #DarkSalmon
B->B: Process request
B->A: return message
deactivate B
A->B: Another request
activate B
B->B: Process another request
destroy B
@enduml

image-20231017170510845

在这个示例中,当 Object A 向 Object B 发送请求时,Object B 被激活并处理请求。处理完成后返回消息,Object B 变为非激活状态。随后,Object A 发送另一个请求,Object B 再次被激活并处理请求。最后,Object B 的生命周期结束,生命线显示为带有❌的矩形。

激活、撤销、创建的快捷语法:

在指定目标参与者后,可以立即使用以下语法:

  • ++ 激活目标(可选择在后面加上[#color])
  • -- 撤销激活源
  • ** 创建目标实例
  • !! 摧毁目标实例
@startuml
participant "Object A" as A
participant "Object B" as B
A->B: Request
B++ #DarkSalmon
B->B: Process request
B-->A: return message
B-- 
A->B: Another request
B++ #DarkSalmon
B->B: Process another request
@enduml

或者可以使用下面这种写法:

@startuml
participant "Object A" as A
participant "Object B" as B
A->B ++ #DarkSalmon: Request
B->B: Process request
B-->A --: return message
A->"Object C" ** #DarkSalmon: Another request
A->B ++ #DarkSalmon: Another request
B->B !!: Process another request
@enduml

image-20231017172052808

12、return

自动返回,返回的依据是上一个用例。

@startuml
participant "Object A" as A
participant "Object B" as B
A->B: Request
return OK
@enduml

image-20231017171034589

13、创建参与者

可以把关键字create放在第一次接收到消息之前,以强调本次消息实际上是在创建新的对象。

@startuml
participant "Object A" as A
participant "Object B" as B
A->B: Request
create Object as C
B->C: Hi
return OK
@enduml

image-20231017171304432

14、锚点和持续时间

@startuml
!pragma teoz true

{start} Alice -> Bob : start doing things during duration
Bob -> Max : something
Max -> Bob : something else
{end} Bob -> Alice : finish

{start} <-> {end} : 时长5s

@enduml

image-20231017172450569

15、构造类型和圈点

可以使用<<>>给参与者添加构造类型。

在构造类型中,你可以使用(X,color)格式的语法添加一个圆圈圈起来的字符。

@startuml

participant Bob << (C,#ADD1B2) >>
participant Alice << (C,#ADD1B2) >>

Bob->Alice: First message

@enduml

image-20231017172613661

16、包裹参与者

我们可以使用 boxend box 生成一个盒子将**「参与者」**包裹起来,如:

注意包裹的对象是参与者

@startuml
box "This is box" #DarkSalmon
participant "Alice" as A
participant Bob as B
end box
participant Clary as C
autonumber
A-> B: Hello
A->>B: Hello
B-x C: Hello
@enduml

image-20231017173033586

三、外观参数

Skinparam 进阶

我们可以使用skinparam改变字体和颜色。可以在如下场景中使用:

  • 在代码的全局定义中
  • 在引入的文件中
  • 在命令行或者ANT任务提供的配置文件中
@startuml
skinparam backgroundColor #EEEBDC
skinparam handwritten true

skinparam sequence {
ArrowColor DeepSkyBlue
ActorBorderColor DeepSkyBlue
LifeLineBorderColor blue
LifeLineBackgroundColor #A9DCDF

ParticipantBorderColor DeepSkyBlue
ParticipantBackgroundColor DodgerBlue
ParticipantFontName Impact
ParticipantFontSize 17
ParticipantFontColor #A9DCDF

ActorBackgroundColor aqua
ActorFontColor DeepSkyBlue
ActorFontSize 17
ActorFontName Aapex
}

' 正式开始

actor User
participant "First Class" as A
participant "Second Class" as B
participant "Last Class" as C

User -> A: DoWork
activate A

A -> B: Create Request
activate B

B -> C: DoWork
activate C
C --> B: WorkDone
destroy C

B --> A: Request Created
deactivate B

A --> User: Done
deactivate A

@enduml

image-20231017173418569