画图是个有用的技能,尤其是像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 %}