UML图语法和Mermaid语言
Mermaid
Mermaid 介绍
许多工作者的日常工作中,除了写字记录,有时还会需要画一些简单的「示意图」,这些示意图会让我们的文档或报告变得形象生动,便于理解,例如下面这些图:
- 流程图
- 结构关系图
- 进度图或甘特图
- 业务序列图
如果我们恰好同时对 Markdown 的「标记式」记录方法高度认可的话,使用类似 Markdown 形式的语言,快速 「写」一个「流图」会非常方便。
说到 Markdown,在互联网时代,Markdown 被广泛普及运用。
很多人用 Markdown 写博客,网上也有一堆支持 Markdown 的写作工具,甚至 印象笔记 也在近支持 Markdown 语法。
- 对于不少追求效率的朋友来说,Markdown 是近来文字记录领域中难以忽视的方案。
在「绘制流图」的领域当中,也有类似 Markdown 的方案: Mermaid
语言。
流图或关系图,主要强调的是 拓扑关系,流向,节点内容,而不是一些花哨的排版。
这点和 Markdown 秉承的「重内容,重结构,轻排版」的思路有不谋而合之处。
Mermaid的好处
- 易于编辑和生成图画
- 通过 Mermaid,我们不用专门的流图工具(例如:微软的 Visio),我们需要编辑的只是文本,因此不少现成的 Markdown 编辑器都可以用上,如果不看渲染结果,仅作编辑的话,普通文本编辑器都能胜任。
Mermaid 和 Markdown 一样,都是纯文本格式存储的语言。
- 纯文本文件打破了很多软件封闭格式的限制,更加利于用户掌握自己的内容。
- 也易于我们 存储,解析,发送文件内容,而不是受制于特定应用的软件或网站平台。
Mermaid-天然的 Web 友好特性
Mermaid 的核心是一个基于 JS 的解析库,这意味着我们可以把 Mermaid 文本,直接嵌入网页中,而访问者就能 直接看到 渲染后的流图了。
顺便说一下,Mermaid 的 JS 解析库,被评为 2019 年 JS Open Source Awards 「The most exciting use of technology」分类下的大奖。
使用 Mermaid
我们已经知道,Mermaid 本质是一种标记语言,借由一个解析库 将文本 「翻译渲染」成「图画」。
虽然通过一个纯文本编辑器,例如:写字板,我们可以撰写 Mermaid 文本,但显然不能指望这样就可以「渲染」出「绘图」来。这和 Markdown 的原理是一样的,渲染需要专门的编辑器。 好消息是,Mermaid 已经被很多 Markdown 编辑器直接或间接支持。 也就是说直接用现有的 Markdown 编辑器就可以上手一试了,几乎没有额外负担。
这里是部分支持 Mermaid 的编辑器
印象笔记 Markdown 笔记
有道云笔记()
Typora ()
VSCode + Mermaid 插件(代码神奇)
Atom + Mermaid 插件
MermaidJS 官方网页版 编辑器 (后文有参考链接)
需要注意的是,由于 Mermaid 本身还在发展,并非所有特性都能被所有 Markdown 编辑器支持。不过,常见的流图编辑模式已经比较成熟,大多被支持。至于具体渲染效果如何,我们还是要以编辑器的实际输出为准。
Mermaid支持
目前这个 Mermaid 主要可支持的「绘图」
- 流图 (Flow)
- 序列图 (Sequence)
- 甘特图(Gantt)
- 类图(Class)
- 状态迁移图(State)
- 饼分图(Pie)
UML图的设计
简介
在软件工程中,统一建模语言(UML)中的类图是一种静态结构图,它通过显示系统的类、它们的属性、操作(或方法)以及对象之间的关系来描述系统的结构。
维基百科类图是面向对象建模的主要构建块.它用于应用程序结构的一般概念建模,并用于将模型转换为编程代码的详细建模。类图也可以用于数据建模。
类图中的类既表示应用程序中的主要元素、交互作用,也表示要编程的类。
标记块写法
``` mermaid
classDiagram 【这一句下面开始写句法】
+++++++++++++++
内部放markdown语法
参考文档
+++++++++++++++
```
第一个示例
以下代码放入标记块,效果入下图所示
+++++++++++++++
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
+++++++++++++++
句法
UML提供了表示类成员的机制,例如属性和方法,以及关于它们的其他信息。
- 图中一个类的单个实例包含三个间隔:顶部的间隔包含类的名称。它以粗体和居中的形式打印,第一个字母是大写的。
- 它还可能包含描述类性质的可选注释文本。中间隔间包含类的属性。 它们是左对齐的,第一个字母是小写的.底部隔间包含类可以执行的操作。
- 它们也是左对齐的,第一个字母是小写。
句法-类
语法代码
+++++++++++++++
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +Bigdecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
+++++++++++++++
句法-定义类
定义类的方法有两种:
- 使用关键字类(如
class Animal
)显式定义类,这定义了动物类。 - 通过它们之间的关系定义了两个类
Vehicle <|-- Car
。这定义了车辆和汽车两类以及它们之间的关系。
语法代码
+++++++++++++++
classDiagram
class Animal
Vehicle <|-- Car
+++++++++++++++
句法-定义类的成员
UML提供了表示类成员的机制,例如属性和方法,以及关于它们的其他信息。
- Mermaid 根据是否存在括号()来区分属性和函数/方法。
- 带有()的函数/方法被视为函数/方法,而其他函数/方法则被视为属性。
- 有两种方法来定义类的成员,不管使用哪种语法来定义成员,输出仍然是相同的。
- 这两种不同的方法是:使用:(冒号)和成员名关联类的成员,这对于一次定义一个成员很有用。
句法-定义类的成员1
语法代码
+++++++++++++++
classDiagram
class BankAccount
BankAccount : +String owner
BankAccount : +Bigdecimal balance
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
+++++++++++++++
句法-定义类的成员2
- 使用{}括号的类的关联成员,其中成员分组在花括号中。适合同时定义多个成员。
语法代码
+++++++++++++++
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount)
+withdrawl(amount)
}
+++++++++++++++
句法-返回值类型
可以选择使用将返回的数据类型结束方法/函数定义
- (注意:方法定义和返回类型示例之间必须有一个空格):
语法代码
+++++++++++++++
classDiagram
class BankAccount{
+String owner
+BigDecimal balance
+deposit(amount) bool
+withdrawl(amount) int
}
+++++++++++++++
句法-泛型
泛型类型成员可以使用泛型类型(如list)对字段、参数和返回类型进行定义,方法是将该类型封装在~(曲线)中。
- 注意:嵌套类型声明(如list<list>>)目前不受支持,这可以作为类定义方法的一部分来完成:
语法代码
+++++++++++++++
classDiagram
class Square~Shape~{
int id
List~int~ position
setPoints(List~int~ points)
getPoints() List~int~
}
Square : -List~string~ messages
Square : +setMessages(List~string~ messages)
Square : +getMessages() List~string~
+++++++++++++++
句法-访问类型
- 要指定类成员的可见性(即任何属性或方法),这些符号可以放在成员名称之前,它是可选的。
+ | Public |
---|---|
- | Private |
# | Protected |
~ | Package/Internal |
-
注意,还可以在方法定义中添加其他分类器,方法的末尾添加以下符号,即
()
之后. -
*
Abstract e.g.:someAbstractMethod()*
-
$
Static e.g.:someStaticMethod()$
句法-定义关系
关系是一个通用术语,涵盖在类图和对象图上找到的特定类型的逻辑连接。
- UML下为类定义了不同类型的关系,目前支持关系
类型 | 描述 |
---|---|
<|- - | 继承 |
*- - | 组合 |
o- - | 聚合 |
- -> | 关联 |
- - | 链接(固态) |
..|> | 依赖 |
.. | 链接(虚线) |
关系句法-示例
以下代码放入标记块,效果入下图所示
+++++++++++++++
classDiagram
classA <|-- classB
classC *-- classD
classE o-- classF
classG <-- classH
classI – classJ
classK <… classL
classM <|… classN
classO … classP
+++++++++++++++
关系句法-标签示例
我们可以用标签来描述两个类之间关系的性质。
+++++++++++++++
classDiagram
classA --|> classB : Inheritance
classC --* classD : Composition
classE --o classF : Aggregation
classG --> classH : Association
classI – classJ : Link(Solid)
classK …> classL : Dependency
classM …|> classN : Realization
classO … classP : Link(Dashed)
+++++++++++++++
关系句法-箭头朝向
此外,箭头也可以在相反的方向使用:
语法代码
+++++++++++++++
classDiagram
classA <|-- classB : implements
classC *-- classD : composition
classE o-- classF : association
+++++++++++++++
关系上的基数/多重性
类图中关系的基数/多重性表示一个类与另一个类实例链接的实例数。
- 例如,一家公司将有一名或多名员工,但每个员工只为一家公司工作。多重性符号被放置在一个关联的末端附近。
不同的基数选择如下:
不同的基数选择如下:
1
Only 1
0..1
Zero or One
1..*
One or more
*
Many
n
n {where n>1}
0..n
zero to n {where n>1}
1..n
one to n {where n>1}
基数可以很容易地定义,将基数文本放在引号中“在给定箭头之前(可选)和(可选)之后”。
语法代码
+++++++++++++++
classDiagram
Customer “1” --> “" Ticket
Student “1” --> "1…” Course
Galaxy --> “many” Star : Contains
+++++++++++++++
对类进行注释
可以用特定的标记文本对类进行注释,这就像类的元数据,清楚地说明了类的性质。
- 一些常见的注释示例
语法代码
+++++++++++++++
classDiagram
class Shape
<> Shape
+++++++++++++++
- 在嵌套结构和类定义中。例如:
语法代码
+++++++++++++++
classDiagram
class Shape{
<<interface>>
noOfVertices
draw()
}
class Color{
<<enumeration>>
RED
BLUE
GREEN
WHITE
BLACK
}
+++++++++++++++
注释
可以在类图中输入,解析器将忽略它。
- 注释需要在它们自己的行上,并且必须以%%(双%符号)作为前缀。
- 注释开始到下一行后的任何文本都将被视为注释,包括任何类关系图语法。
语法代码
+++++++++++++++
classDiagram
%% This whole line is a comment classDiagram class Shape <<interface>>
class Shape{
<<interface>>
noOfVertices
draw()
}
+++++++++++++++
交互[csdn的markdown不会生效,需专业软件]
可以将单击事件绑定到节点,单击可以导致javascript回调或将在新浏览器选项卡中打开的链接。
- 注意:在使用
securityLevel=‘strict’
时禁用了此功能,在使用securityLevel=‘loose’
时启用了此功能。 - 在声明了所有类之后,您将在单独的行上定义这些操作。
action className “reference” “tooltip”
click className call callback()
“tooltip” click className href “url” “tooltip”
- action is either link or callback, depending on which type of interaction you want to have called
- className is the id of the node that the action will be associated with
- reference is either the url link, or the function name for callback.
- (optional) tooltip is a string to be displayed when hovering over element (note: The styles of the tooltip are set by the class .mermaidTooltip.)
- note: callback function will be called with the nodeId as parameter.
交互示例1
URL Link:
classDiagram
class Shape
link Shape “http://www.github.com” “This is a tooltip for a link”
class Shape2
click Shape2 href “http://www.github.com” “This is a tooltip for a link”
Callback:
classDiagram
class Shape
callback Shape “callbackFunction” “This is a tooltip for a callback”
class Shape2
click Shape2 call callbackFunction() “This is a tooltip for a callback”
<script>
var callbackFunction = function(){
alert(‘A callback was triggered’);
}
<script>
- 成功的工具提示功能和链接到URL的能力可以从0.5.2版本中获得。
classDiagram
class Shape
link Shape "http://www.github.com" "This is a tooltip for a link"
class Shape2
click Shape2 href "http://www.github.com" "This is a tooltip for a link"
<script>
var callbackFunction = function(){
alert('A callback was triggered');
}
<script>
初学者提示,一个在html上下文中使用交互式链接的完整示例:
<body>
<div class="mermaid">
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
callback Duck callback "Tooltip"
link Zebra "http://www.github.com" "This is a link"
</div>
<script>
var callback = function(){
alert('A callback was triggered');
}
var config = {
startOnLoad:true,
securityLevel:'loose',
};
mermaid.initialize(config);
</script>
</body>