PlantUML-时序图

简单介绍

时序图(Sequence Diagram),又名序列图、循序图、顺序图,是一种UML交互图。它通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。它可以表示用例的行为顺序,当执行一个用例行为时,其中的每条消息对应一个类操作或状态机中引起转换的触发事件。

PlantUML使用->箭头将一条消息连接两个对象(参与者)。对象本身不需要特别声明。如果想使用虚线箭头,则使用–>。箭头方向调转<-和<–也是可以正常使用的。使用反向箭头画出的图形不会有变化,只是文档更易于理解。需要注意的是,反向箭头只在时序图中可以这样使用,在其他Plant UML的时序图中则含义不完全相同。

我们可以试着写一个基本的例子:

@startuml
张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你
张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
@enduml

画出的时序图如下:

基本示例

代码注释

在uml文档中,使用单引号’ 表示该行后面的都为注释。如果需要注释多行,则使用/’ 和 ‘/作为注释的开始和结束。

例如对前面的示例代码进行注释:

@startuml
张三 -> 李四 : 我要借钱
李四 -->张三 : 借给你
/'张三 ->李四 : 我要还钱
李四 --> 张三 : 收到欠款'/
@enduml

则得到的时序图如下:

注释示例

声明参与者对象

可以通过事先声明的方式,使参与者在时序图中保持确定的顺序。声明可以使用participant关键字,除此以外,还可以使用以下关键字:

  • actor
  • boundary
  • control
  • entity
  • database

使用这些关键字画出的参与者对象的图案稍有不同,但是含义相同。示例如下:

@startuml
participant par
actor act
boundary bou
control con
entity ent
database dat

par->act : to actor
par->bou : to  boundary
par->con : to control
par->ent : to entity
par->dat : to database
@enduml

不同的参与者

另外,还可以在声明参与者对象的时候,通过as关键字来为对象赋予一个简单的别名,需要注意图中显示的字要用双引号引起来。除此之外,声明时还可以对对象的图案指定背景颜色。

示例如下:

@startuml
participant  as par
actor act #FF0000
boundary bou #FF00
control con #FF
entity ent #FFFF00
database dat #FFFF

par->act : to actor
par->bou : to  boundary
par->con : to control
par->ent : to entity
par->dat : to database
@enduml

别名和背景色

双引号非声明的参与者对象

我们可以在箭头指向对象的时候,直接使用非声明的对象。并且,对于长句子,或者有特殊符号的字符串,可以使用双引号引起来。在箭头指向的语句中,也可以通过as关键字,为双引号定义的参与者对象设置别名。

@startuml
张三 ->"Tom()": Hello
"Tom()" -> "牛儿还在山上吃草,放牛的却不知道哪里去了的王二小" as wang: Hi
wang -->: How are you
@enduml

双引号与别名

发给自己的消息

参与者对象,除了将消息发送给其他参与者外,还可以将消息发给自己。消息如果有多行,可以用\n进行换行。

@startuml
张三 ->"Tom()" : Hello
"Tom()"->"牛儿还在山上吃草,放牛的却不知道哪里去了的王二小" as wang : Hi
wang -->"Tom()" : How are you
wang -> wang : 我要把鬼子引到埋伏圈去!让八路军把这些鬼子都干掉~
@enduml

发给自己消息

箭头类型

时序图的箭头除了常用的->以外,还可以指定不同类型的箭头。它们分别是:

  • 箭头末端为一把叉。表示消息丢失。
  • 使用\或者/来代替<>,可以得到只有上半部或者下半部的箭头。
  • 使用两个箭头符号(\\//或者>><<),使箭头变为细线箭头。
  • 使用--代替-,可以变为虚线箭头。
  • 在箭头末尾增加一个o,可以在箭头末尾增加一个O。
  • 可以使用双向箭头。

为了更直观的展示箭头样式,请看下面的示例:

@startuml

阴 -> 阳
阴 --> 阳
阴 ->x 阳
阴 ->> 阳
阴 -\ 阳
阴 -\\ 阳
阴 /-- 阳
阴 //-- 阳
阴 ->o 阳
阴 <--> 阳
阴 <-->o 阳
阴 o<-->x 阳

@enduml

箭头类型

箭头颜色

箭头除了类型可以变化外,箭头的颜色也是可以改变的。指定箭头颜色的方式,就是在箭头符号的第一个字符后插入颜色标记[#color]

例如:

@startuml

树木 -[#green]> 树林
树林 -[#00FF00]> 森林
树林 <- [#red]-- 森林 
树木 <- [#FF0000]-- 树林

@enduml

箭头颜色

消息数字序号

很多时候,时序图消息太多,我们需要在消息上增加序号以理清先后顺序。在PlantUML中,我们可以使用autonumber关键字,就可以自动为消息加上数字序号。例如:

@startuml
autonumber
张三 ->李四 : 我要借钱
李四 --> 张三 : 借给你
张三 ->李四 : 我要还钱
李四 --> 张三 : 收到欠款
@enduml 

消息序号

autonumber除了这样单独使用外,还可以指定开始的数字序号,和每次递增的数字。如果只使用开始序号,则使用autonumber 'start',如果还需要指定每次递增的数字,则使用autonumber 'start' 'increment'。例如:

@startuml
autonumber
张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你
autonumber <span class="hljs-number">12</span>
张三 ->李四 : 我要还钱
李四 -->张三 : 收到欠款
autonumber
张三 ->李四 : 我还要借钱
李四 --> 张三 : 不借了
@enduml

序号指定开始和自增

另外,我们还可以指定数字序号的格式。使用方法是在autonumber后用双引号指定数字序号格式。数字需要的格式指定方式为Java的DecimalFormat方式。(0表示数字,不足的时候占位,#表示数字,不足时不占位)。在格式化的双引号中,还可以使用一些html标签。例如:

@startuml
autonumber "<b>[000]"

张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你

autonumber 12 <b>(<u>###</u>)
张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
autonumber 20 5 <font color=red>MSG #"
张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了

@enduml

序号格式自定义

除此之外,还可以使用autonumber stop停止消息序列计数,然后再通过autonumber resume 'increment' 'format',继续计数。这里就不再写例子示范了。

标题

@startuml
title 借钱与还钱的故事
张三 ->李四 : 我要借钱
李四 --> 张三 : 借给你
@enduml

时序图标题

图表说明

legend关键字与endlegend关键字配合使用,为图表配一段说明文字。可以指定rightleft或者center来指定说明的对齐位置。例如:

@startuml
legend center
这是一个借钱与还钱发生的故事。
故事发生在一个夜黑风高的晚上……
endlegend

张三 -> 李四 : 我要借钱
李四 -->张三 : 借给你
@enduml

图表说明

图表分割

当时序图过长,或者处于某种逻辑考虑时,需要将图表分割为几部分。这时可以使用newpage关键字。例如:

@startuml
张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你
newpage
张三 ->李四 : 我要还钱
李四 --> 张三 : 收到欠款
newpage 最后的标题
张三 ->李四 : 我还要借钱
李四 -->张三 : 不借了
@enduml

这将生成三张图片:
图1

图2

图3

消息分组

为了让时序图消息更有逻辑性,我们常需要对消息进行分组框起来。在PlantUML中,可以使用一下关键字对消息进行分组:

  • alt/else
  • opt
  • loop
  • par
  • break
  • critical
  • group (后接需要显示的字符)

除了group以外,其他关键词后可以接字符串,让其显示在分组框的上方居中位置。另外,分组之间可以嵌套。例如:

@startuml
alt 借钱案例
张三 ->李四 : 我要借钱
loop 循环借钱<span class="hljs-number">100</span>次
group 成功案例
李四 --> 张三 : 借给你
end
张三 ->李四 : 我要还钱
李四 --> 张三 : 收到欠款
end
else 借钱失败
张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
end
@enduml

消息分组

为消息添加注释

很多时候,我们需要在时序图中对消息进行注释,以便做详细的说明。在PlantUML中,可以紧跟消息箭头语句之后,使用note left或者note right关键字来添加注释。如果注释有多行,可以在多行注释后,通过end note来结束注释。示例:

@startuml
张三 -> 李四 : 我要借钱
note left: 我借钱肯定会还你的!
李四 --> 张三 : 借给你
note right: 我相信你肯定会还我钱的!
张三 -> 李四 : 我要还钱
note left
有借有还,
再借不难!
end note
李四 --> 张三 : 收到欠款
note right: 有诚信!
张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
@enduml

这里写图片描述

为参与者对象添加注释

注释除了添加到消息外,还可以直接在时序图中添加到参与者对象上。使用note left ofnote right ofn\\\ote over关键字即可实现。同样,可以在关键字语句后加颜色来改变注释的颜色。另外,也可以与note end组合使用,来添加多行注释。

@startuml
participant 张三
participant 李四
note left of 张三 #00FF00
我的名字叫张三,
家里有房又有田。
谁知来了个李四,
从此生活大变样。
end note
note right of 李四: 我是李四大哥
note over 张三: 谁敢比我惨~~~
note over 李四: 我比你更惨~~~
note over 张三,李四 #red
左手一只鸡,
右手一只鸭,
不得禽流感算我瞎!
end note
@enduml

参与者对象注释

注释的形状

注释除了note的形状以外,还可以使用hnoternotehnote表示六边形,rnote表示长方形。示例:

@startuml

participant 张三
participant 李四

rnote left of 张三 #00>FF00
我的名字叫张三,
家里有房又有田。
谁知来了个李四,
从此生活大变样。
end note
note right of 李四: 我是李四大哥
note over 张三: 谁敢比我惨~~~
note over 李四: 我比你更惨~~~
hnote over 张三,李四 #red
左手一只鸡,
右手一只鸭,
不得禽流感算我瞎!
end note
@enduml

不同形状的注释

Creole和HTML格式

首先,可以使用Creole定义文本格式。它包括:

  • **黑体**
  • //斜体//
  • ""等宽字体""
  • --删除线--
  • __下划线__
  • ~~ 波浪线~~

除此外,在note中还可以使用一些html标签:

<back:red></back> 背景色
<size:18></size> 字体大小
<u:red></u> 下划线
<color red></color>字体颜色
<s:red></strike>删除线
<w:FF33FF></w> 波浪线
<img source.jpg>图片

示例:

```html @startuml

participant 张三
participant 李四

张三 -> 李四 : 我要借钱
note left: 我借钱肯定会还你的!

李四 -->张三 : 借给你
note right: <u:blue>我相信你肯定会<s:green>还我钱的!

张三 -> 李四 : <size:20>我要还钱
note left
有借有还,
–再借不难!–
end note

李四 --> 张三 : 收到欠款
note right: 有诚信!

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了

@enduml









<p><img src="https://img-blog.csdn.net/20170524175927658?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhfd2Vpcg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="自定义文本格式" title=""></p> 
<h1 id="分割线"><a name="t16"></a><a name="t16"></a>分割线</h1> 
<p>我们可以将时序图按照逻辑步骤,使用分割线,将时序图分割为多个不同的步骤阶段。分割线是需要使用<code>==</code>关键字。示例:</p> 

```html
@startuml

== 借钱阶段 ==

张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你

== 还钱阶段 ==

张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款

== 再次借钱阶段 ==

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了

@enduml

分割线

引用

使用ref over可以为参与者对象指定引用组件。示例:

@startuml</span>

participant 杰瑞
actor 汤姆

ref over 杰瑞,汤姆 : 初始化

杰瑞 -> 汤姆 : Hello~

ref over 汤姆
多行表达,
就应该这样!
end ref

@enduml

引用

延时

在时序图中,我们可以指定两条消息之间的延时。并且可以为这个延时添加文字说明。需要使用的关键字为...。示例:

```html @startuml

张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你

… 八百年后 …

张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款

… 一天后 …

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了

@enduml


<p><img src="https://img-blog.csdn.net/20170524181422004?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhfd2Vpcg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="延时" title=""></p> 
<h1 id="间隔空间"><a name="t19"></a><a name="t19"></a>间隔空间</h1> 
<p>使用<code>|||</code>关键字可以为上下两条内容多分隔出一定空间。另外,还可以使用<code>||45||</code>来指定分隔空间的具体像素。示例:</p> 

```html
@startuml

张三 -> 李四 : 我要借钱
李四 --> 张三 : 借给你
|||
张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
||50||
张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
@enduml

间隔空间

生命线的激活与销毁

activatedeactivate关键字用来指明参与者对象的活跃周期。当一个参与者对象被激活,则表示它的活跃周期开始,生命线变为长方形。activatedeactivate关键词用在触发激活的消息之后。

除此外,还可以使用destroy关键字,它表示参与者对象的生命线结束。示例:

@startuml

张三 -> 李四 : 我要借钱
activate 张三
activate 李四

李四 -> 王五 : 你给他担保我才借
activate 王五

王五 --> 李四 : 我给他担保 
destroy 王五

李四 --> 张三 : 借给你

张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
deactivate 李四

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
deactivate 张三
@enduml

生命线生命周期

除此外,生命线还可以嵌套。也就是一个参与者对象可以多次activatedeactivate。另外,可以为生命线指定背景色。示例:

@startuml

张三 -> 李四 : 我要借钱
activate 张三
activate 李四

李四 -> 李四 : 四处筹钱
activate 李四 #FFBBBB

李四 -> 王五 : 你给他担保我才借
activate 王五

王五 --> 李四 : 我给他担保 
destroy 王五

deactivate 李四

李四 --> 张三 : 借给你

张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
deactivate 李四

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
deactivate 张三
@enduml

生命线的嵌套

动态创建参与者对象

在这之前,我们讨论的情况都是参与者在时序图一开始的时候都已经存在。然而实践中,我们经常会遇到某些参与者对象是在时序图的某个阶段才动态创建出来的。

在PlantUML中,我们可以使用create关键字来动态创建参与者对象。其后紧跟一条发送给它的消息,以表明是由这条消息触发了创建这个参与者对象。示例:

@startuml
张三 -> 李四 : 我要借钱
activate 张三
activate 李四

李四 -> 张三 : 风险有点大,有担保吗?

create 王五
张三 -> 王五 : 我来虚拟个担保人
activate 王五

王五 --> 李四 : 我给他担保 
destroy 王五

李四 --> 张三 : 借给你

张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
deactivate 李四

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
deactivate 张三
@enduml

动态创建参与者对象

进出消息

当我们需要将注意力放在一个参与者对象时,我们只关心它的消息进出情况。因此,这样的时序图只需要一个参与对象,然后通过[]配合箭头来表示进出消息。示例:

@startuml

张三 ->] : 我要借钱
activate 张三

[--> 张三 : 风险有点大,有担保吗?
activate 张三 #FFBBBB

张三 -> 张三 : 我来虚拟个担保人

[--> 张三 : 借给你
deactivate 张三

张三 ->] : 我要还钱
[--> 张三 : 收到欠款

张三 ->] : 我还要借钱
[--> 张三 : 不借了
deactivate 张三
@enduml 

进出消息

固定版式和字母标记

在参与者对象声明时,使用<<>>可以生成固定版式标记。在这个版式中,可以使用指定颜色的圆圈的字母标记。标记的方法是,在版式中使用(X,color)。示例:

@startuml
participant "放牛的王二小" as 王 <<自动生成>>
participant 鬼子 <<(O,#FF0000) 自动生成>>
王 -> 鬼子 : 带你去埋伏圈  
@enduml 

版式和字母标记

固定版式中可以没有字符,这样就可以只有字母标记了。示例:

@startuml
participant "放牛的王二小"  as 王 <<(X,#0FF00)>>
participant 鬼子 <<(O,#FF0000)>>
王 -> 鬼子 : 带你去埋伏圈  
@enduml

只有字母标记

参与者对象组合

有时候多个参与者对象构成了一个更大的逻辑对象。这时,我们可以将这多个参与者对象用一个框框起来,表达它们逻辑上的关联。为了画出这样的需求,我们可以使用boxend box组合来将参与者对象放到一起。box关键字后面,可以接一个方框的标题,和指定方框的背景色。示例:

@startuml

box "解放军部队" #LightBlue
participant 将军
participant 士兵
end box

participant 敌人

将军 -> 士兵 : 指挥
士兵 -> 敌人 : 消灭
@enduml

参与者对象组合

去掉底部的重复参与者对象

之前我们画出的所有时序图,顶部和底部都对称地显示了相同的参与者对象。为了图标更为简洁,我们有时需要去掉底部重复的对象,也可以表达相同的含义。这时,我们需要使用hide footbox关键字。示例:

@startuml

hide footbox
title  "八年抗战开始了" 

box "解放军部队" #LightBlue
participant 将军
participant 士兵
end box

participant 敌人

将军 -> 士兵 : 指挥
士兵 -> 敌人 : 消灭
@enduml

去底

皮肤参数

为了时序图更美观,PlantUML还可以使用skinparam关键字来统一定义字体、颜色以及其他外观风格。先看一个简单的例子:

@startuml

skinparam sequenceArrowThickness  2 
skinparam roundcorner  20
skinparam maxmessagesize  60
skinparam sequenceParticipant underline

张三 -> 李四 : 我要借钱
activate 张三
activate 李四

李四 -> 李四 : 四处筹钱
activate 李四 #FFBBBB

李四 -> 王五 : 你给他担保我才借
activate 王五

王五 --> 李四 : 我给他担保 
destroy 王五

deactivate 李四

李四 --> 张三 : 借给你

张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
deactivate 李四

张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
deactivate 张三
@enduml

简单皮肤风格

除此外,PlantUML还支持更多的呈现风格个性化,特别是手写风格看起来非常个性化。例如下面一个稍复杂的例子:

@startuml
skinparam backfroundColor #EEEBDC
skinparam handwritten  true
skinparam sequence {
    ArrowColor DeepSkyBlue
    ActorBorderColor blue
    LifeLineBorderColor blue
    LifeLineBackgroundColor #A9DCDF

    ParticipantBorderColor DeepSkyBlue
    ParticipantBackgroundColor DodgerBlue
    ParticipantFontName Aapex
    ParticipantFontColor #A9DCDF

    ActorBackgroundColor aqua
    ActorFontColor DeepSkyBlue
    ActorFontSize <span class="hljs-number">17</span>
    ActorFontName Aapex
}
张三 -> 李四 : 我要借钱
activate 张三
activate 李四
李四 -> 李四 : 四处筹钱
activate 李四 #FFBBBB
李四 -> 王五 : 你给他担保我才借
activate 王五
王五 --> 李四 : 我给他担保 
destroy 王五
deactivate 李四
李四 --> 张三 : 借给你
张三 -> 李四 : 我要还钱
李四 --> 张三 : 收到欠款
deactivate 李四
张三 -> 李四 : 我还要借钱
李四 --> 张三 : 不借了
deactivate 张三
@enduml

个性化

结束语

到这里,使用PlantUML画时序图的捣鼓就告一个段落了。最后放上一个最近工作中画的一个物联网设备APP端调用支付宝充值服务费的时序图来结束本文吧~

支付宝时序图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值