在 Markdown 中嵌入 UML 文档
Markdown是网络书写语言,特别适合程序员书写文档:
- 全文本格式,方便进行
diff
,patch
和版本的管理; - 格式直观,简单易学,便于书写和阅读;
- 兼容 HTML,能方便地转换为 pdf,doc等格式;
- 支持 Linux,Windows,Mac;
- 支持内嵌代码和语法高亮;
估计只是方便版本管理,就能吸引很多程序员的兴趣,特别是需要团队一起参与书写文档的时候。感兴趣的可以参考官方网站,或者以前写的一份使用 Markdown 的 slides。
但是毕竟Markdown只是书写语言,不是程序设计语言,如果我们需要嵌入 UML 的时候,不可避免地需要其他专业软件的支持。这里介绍几种利用网络服务,可以直接在Markdown文档中嵌入的 UML 建模图:
用例图
角色(Actor)
使用
[角色名]
表示角色。<img src="http://yuml.me/diagram/scruffy/usecase/[Customer]" >
用例(Use Case)
使用
(用例名)
表示用例,-
表示角色和用例之间的关联。<img src="http://yuml.me/diagram/scruffy/usecase/[Customer]-(Login),[Customer]-(Logout)" >
备注(Notes)
如果用例名以
note:
开头,表明那是一个备注,可以用{bg:颜色名}
定义备注的背景色。<img src="http://yuml.me/diagram/scruffy/usecase/[Customer]-(Login), [Customer]-(note: Cust can be registered or not{bg:beige})" >
角色继承(Actor Inheritance)
使用符号
^
表示角色之间的继承关系。<img src="http://yuml.me/diagram/scruffy/usecase/[Cms Admin]^[User], [Customer]^[User], [Agent]^[User]" >
扩展和包含(Extends and Includes)
使用
>
表示用例之间的包含关系,<
表示用例的扩展。<img src="http://yuml.me/diagram/scruffy/usecase/(Login)<(Register),(Login)<(Request Password Reminder),(Register)>(Confirm Registration)" >
完整示例
<img src="http://yuml.me/diagram/nofunky/usecase/(note: figure 1.2{bg:beige}), [User]-(Login),[Site Maintainer]-(Add User),(Add User)<(Add Company),[Site Maintainer]-(Upload Docs),(Upload Docs)<(Manage Folders),[User]-(Upload Docs), [User]-(Full Text Search Docs), (Full Text Search Docs)>(Preview Doc),(Full Text Search Docs)>(Download Docs), [User]-(Browse Docs), (Browse Docs)>(Preview Doc), (Download Docs), [Site Maintainer]-(Post New Event To The Web Site), [User]-(View Events)" >
YUML支持3种图示风格,分别是:
- plain
- scruffy
- boring
你可以对比下列图示的不同风格:
活动图
动作(Action)
用
(状态名)
表示一个状态,其中(start)
和(end)
分别表示开始状态和结束状态,箭头->
表示状态的转换。<img src="http://yuml.me/diagram/nofunky/activity/(start)->(Boil Kettle)->(end)" >
判断和限制(Decisions and Constraints)
使用
<判断名>
表示一个条件判断,其后跟[条件]->
表示满足条件后状态的转换;用不同的判断名
来标识不同的判定位置。<img src="http://yuml.me/diagram/nofunky/activity/(start)-><a>[kettle empty]->(Fill Kettle)->(Boil Kettle),<a>[kettle full]->(Boil Kettle)->(end)" >
分支合并(Fork/Join)
使用
||
表示分支或者合并点。<img src="http://yuml.me/diagram/nofunky/activity/(start)-><a>[kettle empty]->(Fill Kettle)->|b|,<a>[kettle full]->|b|->(Boil Kettle)->|c|,|b|->(Add Tea Bag)->(Add Milk)->|c|->(Pour Water)->(end),(Pour Water)->(end)" >
对象(Objects)
符号
[]
表示一个对象。<img src="http://yuml.me/diagram/nofunky/activity/(start)->[Water]->(Fill Kettle)->(end)" >
连接器名称(Connector Name)
在
->
中加入名称,-名称>
表示命名连接器。<img src="http://yuml.me/diagram/nofunky/activity/(start)-fill>(Fill Kettle)->(end)" >
类图
关联(Association)
类名用
[]
表示,->
表示定向关联,-
表明关联。<img src="http://yuml.me/diagram/nofunky/class/[Customer]->[Billing Address]" >
基数(Cardinality)
基数-基数>
表明关联的基数,其中基数可以为0
,1
,0..*
,*
等任意定义的值。<img src="http://yuml.me/diagram/nofunky/class/[Customer]1-0..*[Address]" >
定向关联(Directional Association)
定向关联
->
可以定义名称:-名称>
。<img src="http://yuml.me/diagram/nofunky/class/[Order]-billing >[Address], [Order]-shipping >[Address]" >
颜色和UTF8字符(Splash of Colour And UTF-8)
类图可以用
{bg:颜色名}
定义显示的背景颜色。<img src="http://yuml.me/diagram/nofunky/class/[❝Customer❞{bg:orange}]❶- ☂>[Order{bg:green}]" >
聚合(Aggregation)
聚合表示比关联更强的关联关系,使用
<>->
或者+->
来表示。<img src="http://yuml.me/diagram/nofunky/class/[Company]<>-1>[Location], [Location]+->[Point]" >
组成(Composition)
组成表示比聚合更强的关联关系,使用
++->
来表示。<img src="http://yuml.me/diagram/nofunky/class/[Company]++-1>[Location]" >
备注(Notes)
使用
[note:注解内容]
表示备注,同样备注可以自定义颜色{bg:颜色名}
。<img src="http://yuml.me/diagram/nofunky/class/[Customer]<>1->*[Order], [Customer]-[note: Aggregate Root{bg:cornsilk}]" >
继承(Inheritance)
使用
^-
表示类的继承,右边的类是子类。<img src="http://yuml.me/diagram/nofunky/class/[Wages]^-[Salaried], [Wages]^-[Contractor]" >
接口继承(Interface Inheritance)
接口继承用
^-.-
来表示。<img src="http://yuml.me/diagram/nofunky/class/[<<ITask>>]^-.-[NightlyBillingTask]" >
依赖(Dependencies)
类的依赖用
-.->
来表示,依赖是最弱的关联关系,一般用来表示类方法的参数或者实现用到了依赖类。<img src="http://yuml.me/diagram/nofunky/class/[HttpContext]uses -.->[Response]" >
接口(Interface)
和类名相比,接口的名称一般包含在
<<>>
中。<img src="http://yuml.me/diagram/nofunky/class/[<<IDisposable>>;Session]" >
类定义(Class with Details)
可以在类符号
[]
中定义类的所有成员。使用|
表示类名与类成员变量和成员函数的分割符,不同的成员之间用;
隔开,使用+
,-
分别表示公开和私有成员。<img src="http://yuml.me/diagram/nofunky/class/[User|+Forename+;Surname;+HashedPassword;-Salt|+Login();+Logout()]" >
完整的示例
<img src="http://yuml.me/diagram/nofunky/class/[note: You can stick notes on diagrams too!{bg:cornsilk}],[Customer]<>1-orders 0..*>[Order], [Order]++*-*>[LineItem], [Order]-1>[DeliveryMethod], [Order]*-*>[Product], [Category]<->[Product], [DeliveryMethod]^[National], [DeliveryMethod]^[International]" >
时序图
首先在文件头加入如下 javascript 文件:
<script type="text/javascript" src="http://www.websequencediagrams.com/service.js"></script>
同步/异步/返回消息(Synchronous/Asynchronous/Return Message)
一般使用实心箭头
->
表示同步消息或调用,开箭头->>
表示异步消息或调用,虚箭头-->
或-->>
表示返回消息。<div class=wsd wsd_style="rose" ><pre> # This is a comment. Alice->Bob: Filled arrow Alice->>Bob: Open arrow Bob-->Alice: Dotted line Bob-->>Alice: Dotted Line, open arrow </pre></div>
# This is a comment. Alice->Bob: Filled arrow Alice->>Bob: Open arrow Bob—>Alice: Dotted line Bob—>>Alice: Dotted Line, open arrow
定义参与者的顺序
通过
participant
可以定义角色
在时序图中的显示顺序,而不是按照缺省的参与者被使用顺序来显示。并且可以定义参与者的别名。<div class=wsd wsd_style="rose" ><pre> participant Bob participant Alice participant "I have a really\nlong name" as L # Alice->Bob: Authentication Request Bob->Alice: Authentication Response Bob->L: Log transaction </pre></div>
participant Bob participant Alice participant “I have a really\nlong name” as L # Alice->Bob: Authentication Request Bob->Alice: Authentication Response Bob->L: Log transaction
自关联消息(Self-Message)
参与者可以发送一个消息给自己。你可以用
\n
将文字切分成多行。<div class=wsd wsd_style="rose" ><pre> Alice->Alice: This is a signal to self.\nIt also demonstrates \nmultiline \ntext. </pre></div>
Alice->Alice: This is a signal to self.\nIt also demonstrates \nmultiline \ntext.
分组消息
通过
alt/else
,opt
和loop
,将消息分组,组头显示分组定义的文本信息,end
关键字用来结束一个分组。分组可以嵌套。<div class=wsd wsd_style="rose" ><pre> Alice->Bob: Authentication Request alt successful case Bob->Alice: Authentication Accepted else some kind of failure Bob->Alice: Authentication Failure opt loop 1000 times Alice->Bob: DNS Attack end end else Another type of failure Bob->Alice: Please repeat end </pre></div>
Alice->Bob: Authentication Request alt successful case Bob->Alice: Authentication Accepted else some kind of failure Bob->Alice: Authentication Failure opt loop 1000 times Alice->Bob: DNS Attack end end else Another type of failure Bob->Alice: Please repeat end
备注(Notes)
使用
note left of
,note right of
和note over
分别定义左/右/中显示的备注,可以包含多行,end note
用来结束该段note
。<div class=wsd wsd_style="rose" ><pre> participant Alice participant Bob # note left of Alice 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: This is displayed over Bob and Alice. </pre></div>
participant Alice participant Bob # note left of Alice 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: This is displayed over Bob and Alice.
生命线的激活和终止(Activation/Destruction)
+
来表示激活被发送者,-
表示终止发送者。destroy
关键字可以将销毁该参与者。<div class=wsd wsd_style="rose" ><pre> User->+A: DoWork A->+B: <<createRequest>> B->+C: DoWork C-->B: WorkDone destroy C B-->-A: RequestCreated A->User: Done </pre></div>
User->+A: DoWork A->+B: <
> B->+C: DoWork C—>B: WorkDone destroy C B—>-A: RequestCreated A->User: Done