碰见PlantUML

我的博客:zhenganwen.tophtml

前言

来到公司实习也快一个月了,最大的体会就是,虽然大部分时间作的是简单的增删该查,但不一样于在学校时写的Demo,你要充分考虑程序的鲁棒性(健壮性)、可扩展性(可维护性)、时间/空间复杂度等。由于是要实际上线的项目,你须要面面俱到,对团队负责。java

因而决定在完成组里任务之余,花时间提升本身的的编码规范、多思考程序设计的可扩展性、性能是否可观等。我以为开发工程师和码农之间的区别是,不只是复制粘贴和以实现功能为最终目标,还要考虑如何更优雅的编码、如何实现代码复用而避免重复动做,这是一种追求,也能给工做带来一种工艺、匠心上的体验。git

因而我想从设计模式下手,学习前辈们多年沉淀下来的优雅的编码技巧。以前曾看过《Head First设计模式》,当时感受写的挺好,可是急于求成,一味地莽着看完了,到如今回想起来却也不记得几分。我以为实战和重复是学习的重要因素,纸上得来终觉浅,绝知此事要躬行,仍是要花时间认真学一遍啊~编程

感受《Head First设计模式》中的内容针对GUI编程的较多,而如今Java主流应用在服务端,再加上看过的书除非是像《深刻理解Java虚拟机》这种往往“”温故而知新”的,我不太愿意看第二遍,因而将目标定在了《图解Java设计模式》上。(原本上当当搜“Java设计模式”发现《Java设计模式及实践》好像还不错并且是针对Java服务端的,但奈何太新网盘上还搜不到PDF资源,而我又经济拮据……)windows

在看设计模式相关的书籍时总有一个感受,当设计模式中的角色较多时很容易把本身搞混,这时一个清晰的Java类图可以高效的帮你理清思路以及如此设计的用意。因而我又折腾的下载了一个IDEA插件PlantUML,自此PlantUML的入坑之路拉开序幕……设计模式

安装及配置

IDEA插件

IDEA中安装好PlantUML插件(和markdown插件相似,有本身的UML描述语言,在编写后能事实反应到UML图中)后,按照官方文档的提示File->New->PlantUML File开始个人第一个类图bash

1565688748017.png

然而,我在编写如上右侧的代码后,右边显示的确实一个异常:markdown

1565688910081.png

这是由于PlantUML依赖Graphviz,咱们须要先下载它(该连接是Windows的.msi安装包,如果其它平台,可在参考https://www.graphviz.org/download/)gitlab

安装以后须要为其配置环境变量GRAPHVIZ_DOT,为安装目录下的/bin/dot.exe,如图性能

1565689168390.png

而后重启IDEAPlantUML标签窗口就能根据你输入的PlangUML language实时绘图了

1565689274652.png

PlantUML

上节是PlantUML做为插件在IDEA中的使用,做为独立的产品,天然也可以独立运行,本节就介绍经过运行jar的方式使用PlantUML

首先下载该产品对应的jar,而后在该jar所在路径运行java -jar plantuml.jar便可启动该应用:

1565690222139.png

而后点击Change Directory选择一个目录做为workspace,这里我选的是D:\Work_Space\UML,后续PlantUML源文件和对应生成的图片都将放在此目录。

workspace中新建源文件,如test.txt,键入以下代码:

@startuml
class HelloWorld
@enduml
复制代码

保存后,在GUI中双击该文件便可打开对应的绘图窗口,而且每次保存源文件都会自动触发从新绘图:

1565690677576.png

类图

使用PlantUML能够画出不少中图,可参考官方文档,本文仅介绍IDEA中类图的画法。

类之间的关系

泛化/IS-A

IS-A一般用来表继承关系,用空心三角形加实线来表示,语法为Parent <|-- Child

@startuml
Person <|-- Child
@enduml
复制代码

image.png

你也能够像下面写代码同样表述关系,extends将被识别

@startuml
class Person{
    age : int
    gender : char
}

class Student extends Person{
    grade : String
}
@enduml
复制代码

image.png

实现

实现通常针对接口,符号为三角形加虚线,语法为Flyable <|.. Plane

@startuml
interface Flyable{
    void fly();
    {abstract} double getSpeed();
}

class Vehicle{
    int speed;
    {abstract} void run();
}

Flyable <|.. Plane
Vehicle <|-- Plane
@enduml
复制代码

image.png

聚合Aggregation

语法:空心菱形加实线Department o-- Employees

Aggregation聚合关系用于表示实体对象之间的关系,表示总体由部分构成的语义,例如一个部门由多个员工组成。与组合关系不一样的是,总体和部分不是强依赖的,即便总体不存在了,部分仍然存在,例如:部门撤销了,人员不会消失,他们依然存在

@startuml
class Employee{
}

class Department{
    Employee[] employees;
}

Department o- Employee
@enduml
复制代码

image.png

一个-会画横线,两个-会画竖线,如o--会画竖线

组合Composition

语法:实心菱形+实线ArrayList *- Element

Composition组合关系是一种强依赖的特殊聚合关系,若是总体不存在了,则部分也不存在了,例如:公司不存在了,部门也将不存在了

@startuml
class Element{

}

class ArrayList{
    Element[] elements
}

ArrayList *- Element
@enduml
复制代码

image.png

因为在Java中,内存管理对于咱们是透明的。不像C语言,可能咱们调用free(company)释放结构体对象company的内存,那么其成员departmentList也会被销毁。Java的自动内存管理机制是只要该对象到GC Roots是可达的(即可以与引用链连上)那就不会被回收。所以,在Java中,这两种关系的界限并不分明。

关联关系Association

语法:实线+箭头,->/<-<--/--><->/<-->

关联关系是用一条直线表示的;它描述不一样类的对象之间的结构关系;它是一种静态关系, 一般与运行状态无关,通常由常识等因素决定的;它通常用来定义对象之间静态的、自然的结构; 因此,关联关系是一种“强关联”的关系;

好比,乘车人和车票之间就是一种关联关系;学生和学校就是一种关联关系;

关联关系默认不强调方向,表示对象间相互知道;若是特别强调方向,以下图,表示A知道B,但 B不知道A;

@startuml
class Controller{
    Service service;
}
class Service{
    Dao dao;
}
class Service2
class Dao
Controller -> Service
Service <-> Service2 
Service -> Dao
@enduml
复制代码

image.png

依赖

语法:

依赖也容易和关联弄混,但与关联关系不一样的是,它是一种临时性的关系,一般在运行期间产生,而且随着运行时的变化, 依赖关系也可能发生变化

显然,依赖也有方向,双向依赖是一种很是糟糕的结构,咱们老是应该保持单向依赖,杜绝双向依赖的产生;

在最终代码中,依赖关系体现为类构造方法及类方法的传入参数,箭头的指向为调用关系;依赖关系除了临时知道对方外,仍是“使用”对方的方法和属性;

@startuml
class UserController{
    void insertUser(User user)
}

class User{

}

UserController .> User
@enduml
复制代码

image.png

关于类图的入门介绍到此为止,有兴趣的同窗可参考官网进一步学习,并在学设计模式以后借助类图梳理流程和思路,以达到事半功倍的效果~

参考资料

相关文章
相关标签/搜索