碰見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

關於類圖的入門介紹到此爲止,有興趣的同窗可參考官網進一步學習,並在學設計模式以後藉助類圖梳理流程和思路,以達到事半功倍的效果~

參考資料

相關文章
相關標籤/搜索