start :foo1; floating note left: This is a note :foo2; note right This note is on several //lines// and can contain <b>HTML</b> ==== * Calling the method ""foo()"" is prohibited end note stop
@enduml
后向活动添加注释
@startuml start repeat :Enter data; :Submit; backward :Warning; note right: Note repeat while (Valid?) is (No) not (Yes) stop @enduml
@startuml :foo1; -> You can put text on arrows; if (test) then -[#blue]-> :foo2; -[#green,dashed]-> The text can also be on several lines and **very** long...; :foo3; else -[#black,dotted]-> :foo4; endif -[#gray,bold]-> :foo5; @enduml
活动图-控制流程:分支和循环
分支(if/else)
@startuml start if (决策点?) then (选项1) :处理选项1; else (选项2) :处理选项2; endif :后续步骤; stop @enduml
while循环
@startuml start
while (数据未处理完?) is (是) :处理一条数据; :更新索引; endwhile (否)
:完成; stop @enduml
使用 while … endwhile 来创建 while 循环。is (是) 指定了循环条件成立时的出口标签。
重复循环
使用 repeat … repeat while 来创建 do-while 循环(先执行后判断)。
@startuml start
repeat :处理一条数据; :更新索引; repeat while (数据未处理完?) is (是) not (否) :完成; stop @enduml
repeat :foo作为开始标注; :读取数据; :生成图片; backward:这是一个后撤行为; repeat while (更多数据?)
stop
@enduml
打断循环 [break]
可以使用 break 关键字跟在循环中的某个行为后面打断循环
@startuml start repeat :测试某事; if (发生错误?) then (没有) #palegreen:好的; break endif ->not ok; :弹窗 "文本过长错误"; repeat while (某事发生文本过长错误?) is (是的) not (不是) ->//合并步骤//; :弹窗 "成功!"; stop @enduml
Switch判断 [switch, case, endswitch]
@startuml start switch (测试?) case ( 条件 A ) :Text 1; case ( 条件 B ) :Text 2; case ( 条件 C ) :Text 3; case ( 条件 D ) :Text 4; case ( 条件 E ) :Text 5; endswitch stop @enduml
并行处理 [fork, fork again, end fork, end merge]
fork 示例
@startuml start fork :行为 1; fork again :行为 2; end fork stop @enduml
fork 和合并示例
@startuml start fork :行为 1; fork again :行为 2; end merge stop @enduml
@startuml start fork :行为 1; fork again :行为 2; fork again :行为 3; fork again :行为 4; end merge stop @enduml
end fork 标注 (或 UML 连接规范)
@startuml start fork :行为 A; fork again :行为 B; end fork {或} stop @enduml
复杂场景
@startuml
start
if (多进程处理?) then (是) fork :进程 1; fork again :进程 2; end fork else (否) :逻辑 1; :逻辑 2; endif
@startuml actor User participant "First Component" as A participant "Second Component" as B order 1 ' B 会因为 order 1 而排在左边第一个 @enduml
形状
@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
@startuml actor Bob #red ' The only difference between actor 'and participant is the drawing participant Alice participant "I have a really\nlong name" as L #99FF99 /' You can also declare: participant L as "I have a really\nlong name" #99FF99 '/
@startuml Alice -> "Bob()" : Hello "Bob()" -> "This is very\nlong" as Long ' You can also declare: ' "Bob()" -> Long as "This is very\nlong" Long --> "Bob()" : ok @enduml
时序图-消息 (Messages)
消息是参与者之间的通信,用箭头表示。
同步消息
同步消息 (Synchronous): ->表示调用并等待返回。实心箭头。
A -> B: doSomething()
异步消息
异步消息 (Asynchronous): -->表示发送后不等待返回。开放箭头。
A --> B: somethingHappened()
返回消息
返回消息 (Return): <- or <--通常可省略,PlantUML 会自动推断。为了清晰,可以显式画出。
A -> B: compute() B <- A: result // 显式地绘制返回消息
给自己发消息
参与者可以给自己发信息,消息文字可以用\n来换行。
@startuml Alice -> Alice: This is a signal to self.\nIt also demonstrates\nmultiline \ntext @enduml
@startuml Alice <- Alice: This is a signal to self.\nIt also demonstrates\nmultiline \ntext @enduml
对消息序列编号
关键字 autonumber 用于自动对消息编号
@startuml autonumber Bob -> Alice : Authentication Request Bob <- Alice : Authentication Response @enduml
@startuml autonumber 10 10 "<b>[000]" Bob -> Alice : Authentication Request Bob <- Alice : Authentication Response
autonumber stop Bob -> Alice : dummy
autonumber resume "<font color=red><b>Message 0 " Bob -> Alice : Yet another authentication Request Bob <- Alice : Yet another authentication Response
autonumber stop Bob -> Alice : dummy
autonumber resume 1 "<font color=blue><b>Message 0 " Bob -> Alice : Yet another authentication Request Bob <- Alice : Yet another authentication Response @enduml
B -> C: DoWork activate C C --> B: WorkDone destroy C
B --> A: RequestCreated deactivate B
A -> User: Done deactivate A
@enduml
嵌套的生命线
@startuml participant User
User -> A: DoWork activate A #FFBBBB
A -> A: Internal call activate A #DarkSalmon
A -> B: << createRequest >> activate B
B --> A: RequestCreated deactivate B deactivate A A -> User: Done deactivate A
@enduml
自动激活
需要与return关键字配合
@startuml autoactivate on alice -> bob : hello bob -> bob : self call bill -> bob #005500 : hello from thread 2 bob -> george ** : create return done in thread 2 return rc bob -> george !! : delete return success
@startuml skinparam responseMessageBelowArrow true Bob -> Alice : hello Bob <- Alice : ok @enduml
时序图-注释信息
普通注释
可以使用note left 或note right 关键字在信息后面加上注释。可以使用end note 关键字有一个多行注释。
@startuml Alice->Bob : hello note left: this is a first note
Bob->Alice : ok note right: this is another note
Bob->Bob : I am thinking note left a note can also be defined on several lines end note @enduml
修改注释背景色
可以使用note left of,note right of或note over在节点(participant)的相对位置放置注释。还可以通过修改背景色来高亮显示注释。以及使用关键字end note来添加多行注释。
@startuml participant Alice participant Bob note left of Alice #aqua This is displayed left of Alice. end note
note right of Alice: This is displayed right of Alice.
note over Alice: This is displayed over Alice.
note over Alice, Bob #FFAAAA: This is displayed\n over Bob and Alice.
note over Bob, Alice This is yet another example of a long note. end note @enduml
时序图-组合消息
可以通过以下关键词来组合消息:
alt/else
opt
loop
par
break
critical
group, 后面紧跟着消息内容
可以在标头(header)添加需要显示的文字(对于group关键字,参看 ‘次级分组标签’)。关键词 end 用来结束分组。注意,分组可以嵌套使用。
@startuml Alice -> Bob: 认证请求
alt 成功情况
Bob -> Alice: 认证接受
else 某种失败情况
Bob -> Alice: 认证失败 group 我自己的标签 Alice -> Log : 开始记录攻击日志 loop 1000次 Alice -> Bob: DNS 攻击 end Alice -> Log : 结束记录攻击日志 end
else 另一种失败
Bob -> Alice: 请重复
end @enduml
时序图-次级分组标签
对于group而言,在标头处的[和]之间可以显示次级文本或标签。
@startuml Alice -> Bob: 认证请求 Bob -> Alice: 认证失败 group 我自己的标签 [我自己的标签2] Alice -> Log : 开始记录攻击日志 loop 1000次 Alice -> Bob: DNS攻击 end Alice -> Log : 结束记录攻击日志 end @enduml
时序图-生命线控制 (Lifeline Control)
创建与销毁:create 和 destroy
User -> A++: new() create B // 创建参与者 B A -> B: initialize() destroy A // 销毁参与者 A
暂停生命线:||| 或 ... 表示时间流逝或等待。
A -> B: request ... B --> A: response ' 中间有一段延迟
给自己发消息:[Participant]->[Participant]
A -> A: internalCall()
时序图-分隔线 (Dividers)
使用 == 来划分不同阶段。
User -> Server: Login == Authentication == Server -> DB: Validate Credentials ... == Data Access == User -> Server: Query Data
时序图-脚注与标题 (Footer and Header)
title Diagram Title: 设置标题。
header: 页眉。
footer: 页脚。
legend / end legend: 添加图例。
title Example Sequence Diagram header Some Header footer Page %page% of %lastpage% User -> System: Interaction legend This is a legend end legend
时序图完整综合示例
示例1
下面是一个综合了以上多种语法的示例,模拟一个用户登录流程。
@startuml 用户登录时序图示例 ' 1. 定义参与者 actor "User" as User participant "Web Browser" as Browser participant "Auth Controller" as Auth participant "Database" as DB database "Redis Cache" as Cache
' 2. 设置标题 title 用户登录流程时序图
' 3. 开始交互 User -> Browser++: 输入用户名/密码,点击登录 Browser -> Auth++: POST /login (credentials)
' 4. 分组:输入验证 group 输入验证 [客户端验证] alt 格式有效 note over Browser, Auth: 用户名密码不为空 Auth -> Cache++: get(captcha_id) return captcha_code Auth -> Auth: validateCaptcha(input, captcha_code) else 格式无效 Auth --> Browser--: 错误:输入格式无效 Browser --> User--: 显示错误消息 return end
' 5. 分组:认证逻辑 == 核心认证 == opt 验证码正确 Auth -> DB++: queryUser(username, password_hash) alt 用户存在且密码正确 DB --> Auth: User object Auth -> Auth: generateSessionToken() Auth -> DB: storeSession(token, user_id) DB --> Auth: OK Auth -> Cache: storeUserProfile(user_id) Cache --> Auth: OK Auth --> Browser--: HTTP 302 (Redirect to home) Browser -> Browser: storeCookie(session_token) Browser --> User--: 重定向到首页 else 认证失败 DB --> Auth: null Auth --> Browser--: 错误:用户名或密码错误 Browser --> User--: 显示错误消息 end else 验证码错误 Auth --> Browser--: 错误:验证码错误 Browser --> User--: 显示错误消息 end
participant "<b>Operator" as OP participant "<b>SM-DP+" as DP participant "<b>LPAd" as LPA participant "<b>eUICC" as E
LPA -> E : [1] ES10b.LoadBoundProfilePackage x N\n(ES8+.InitialiseSecureChannel)
rnote over E #FFFFFF [2] - Verify InitialiseSecureChannel data - Generate Session Keys endnote E --> LPA : Response APDU x N LPA -> E : [3] ES10b.LoadBoundProfilePackage x N\n(ES8+.ConfigureISDP) E --> LPA : Response APDU x N LPA -> E : [4] ES10b.LoadBoundProfilePackage x N\n(ES8+.StoreMetadata) E --> LPA : Response APDU x N
rnote over E #FFFFFF [4a] Verify PPR(s) against RAT [4b] [Verify Enterprise Configuration] endrnote
LPA -> E : [5] [ES10b.LoadBoundProfilePackage x N]\n(ES8+.ReplaceSessionKeys) E --> LPA : [Response APDU x N] LPA -> E : [6] ES10b.LoadBoundProfilePackage x N\n(ES8+.LoadProfileElements) E --> LPA : Response APDU x N \n(ProfileInstallationResult)