PlantUML标签扩展

画图是个有用的技能,尤其是像PlantUML这样用代码画图。

初次大规模接触UML还是在软工课上,各种图眼花缭乱的,甚是枯燥。后来发现有些场景下还是很有用的,比如阅读设计模式或数据库相关书籍的时候。 有时即使不是特别专业的场合,需要画一些简单的框图,也可以利用UML。图片一次画好也就算了,如果还要修改和维护,那简直是灾难。虽然可以保存图片模板之类,比如使用Viso,但是感觉杀鸡用牛刀。。
最适合的莫过于PlantUML这种用代码生成图片的方式,感觉写文档尤其有用。
本篇就作为Hexo集成PlantUML的测试及常用语法参考手册。

项目地址


https://github.com/oohcoder/hexo-tag-plantuml

语法


类图

1
2
3
4
5
6
7
8
{% plantuml %}
class Dummy {
-field1
#field2
~method1()
+method2()
}
{% endplantuml %}

访问级别

  • - 私有
  • ~ 包级私有
  • # 保护
  • + 公有

类的类型标识

1
2
3
4
5
6
{% plantuml %}
abstract AbstractList
interface List
enum TimeUnit
annotation SuppressWarnings
{% endplantuml %}

加备注显示标明

1
2
3
4
5
6
{% plantuml %}
abstract AbstractList << abstract >>
interface List << interface >>
enum TimeUnit << enum >>
annotation SuppressWarnings << annotation >>
{% endplantuml %}

类关系

继承(Inheritance)
...is a...

1
2
3
4
public class Shape {
}
public class Circle extends Shape {
}
1
2
3
{% plantuml %}
Shape <|-- Circle
{% endplantuml %}

实现(Realization)

1
2
3
4
public interface Drawable {
}
public class Brush implements Drawable {
}
1
2
3
4
{% plantuml %}
interface Drawable
Drawable <|.. Brush
{% endplantuml %}

依赖(Dependency)
...uses a...
最弱的关联关系,通常只是简单的传入,在某一时刻持有

1
2
3
4
public class Brush{
public void draw(Shape p) {
}
}
1
2
3
{% plantuml %}
Brush ..> Shape
{% endplantuml %}

联系(Association)
广义的联系。常见单向,双向,量词描述等。

1
2
3
public class Painter {
Brush[] brushes;
}
1
2
3
{% plantuml %}
Painter --> "1..*" Brush
{% endplantuml %}

双方量词描述时,要看对方。比如画家可以有0~n画作,画作有至少一个画家。

1
2
3
4
5
6
public class Painter {
Painting[] paintings;
}
public class Painting {
Painter[] painters;
}
1
2
3
{% plantuml %}
Painter "1..1" -- "0..*" Painting
{% endplantuml %}

聚合(Aggregation)
...has a...
和联系含义混合,可以看作一种狭义的联系。
特指一个容器对象包含另一个对象实例但不维护生命周期。也就是说被包含的对象和容器相对独立,可以脱离容器对象而存在。

1
2
3
4
5
6
public class Brush {
private Color color;
public void setColor(Color color) {
this.color = color;
}
}
1
2
3
{% plantuml %}
Brush o-- Color
{% endplantuml %}

组合(Composition)
...is part of...
最强的关联关系。一个容器对象包含另一个对象的实例并且维护完整的生命周期。
如果销毁此容器,它管理的所有对象都被销毁。

1
2
3
4
5
6
public class Brush {
private Recorder r;
public Brush() {
r = new Recorder();
}
}
1
2
3
{% plantuml %}
Brush *-- Recorder
{% endplantuml %}

时序图

角色定义,名称简写,实虚线,消息文字,生命线

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{% plantuml %}
actor User as U
participant Browser as B
box "Back End" #LightBlue
participant Server as S
database Database as DB
end box
U -> B : click
activate B
B -> S : request
S -> DB : query
DB -> S : result
S -> B : response
B -> U : show
deactivate B
S --> B : notify
B -> B : popup
{% endplantuml %}

箭头样式和文字描述

1
2
3
4
5
6
7
8
9
10
11
12
{% plantuml %}
hide footbox
title Sample
participant Begin as B
participant End as E
B ->x E
B -> E:synchronous message
B ->> E:asynchronous message
B <-- E:return message
B ->o E
B <-> E
{% endplantuml %}

编号

1
2
3
4
5
6
7
8
9
10
11
12
{% plantuml %}
autonumber
participant Begin as B
participant End as E
B -> E
E -> B
... some time ...
|||
autonumber 20
B -> E
E -> B
{% endplantuml %}

状态图

常用状态图

1
2
3
4
5
6
7
8
9
{% plantuml %}
[*] --> Booting : start up
Booting --> Configuration
Configuration --> Ready
Ready --> Configuration
Ready --> Booting : restart
Ready --> Ready : operate
Ready --> [*] : shut down
{% endplantuml %}

嵌套及并发状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{% plantuml %}
state Booting {
[*] -right--> Network
Network:Ready
--
[*] -right--> IO
IO:Ready
--
[*] -right--> Memory
Memory:Ready
}

[*] -right--> Booting
{% endplantuml %}

活动图

条件判断

1
2
3
4
5
6
7
8
9
10
11
{% plantuml %}
start
if (isBird) then (yes)
:fly;
elseif (isFish) then (yes)
:swim;
else (no)
:run;
endif
stop
{% endplantuml %}

循环

1
2
3
4
5
6
7
8
{% plantuml %}
start
while (more data?)
:read data;
:process data;
endwhile
stop
{% endplantuml %}

并行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% plantuml %}
start
if (multiprocessor) then (yes)
fork
:Worker1;
fork again
:Worker2;
end fork
stop
else (no)
:Worker1;
:Worker2;
stop
endif
{% endplantuml %}

泳道

1
2
3
4
5
6
7
8
9
10
11
12
{% plantuml %}
|Method1|
start
:process;
:call;
|#AntiqueWhite|Method2|
:process;
:return;
|Method1|
:process;
stop
{% endplantuml %}