【設(shè)計(jì)模式】10分鐘學(xué)懂UML類圖
UML介紹
自己剛剛參加工作時(shí),剛進(jìn)部門第一周leader讓我熟悉一個(gè)模塊的調(diào)用過程,那個(gè)模塊包含幾十個(gè)類、有上百個(gè)方法,類和類之間關(guān)系錯(cuò)綜復(fù)雜,各種方法調(diào)來調(diào)去,我就畫了一整張紙,密密麻麻,睡醒覺第二天就已經(jīng)看不懂了,簡直裂開,這種感覺記憶尤新,當(dāng)時(shí)leader說”工具不對“,然后從那個(gè)時(shí)候才開始接觸UML。
UML(Unified Modeling Language)是一種統(tǒng)一建模語言,是用來對軟件密集系統(tǒng)進(jìn)行可視化建模的一種語言。
UML圖有很多種,主要包含以下幾類:

但是對于初學(xué)者來說,我們不需要掌握所有的UML圖,才能進(jìn)行系統(tǒng)分析和設(shè)計(jì)工作,否則學(xué)習(xí)的成本太高了。根據(jù)二八原則,一般說來,在UML圖中,只要掌握類圖、用例圖、時(shí)序圖的使用,就能完成80%的工作了。而對于程序員來說,使用最頻繁的又是類圖。因此,本文我們只介紹UML類圖。
抽象類、抽象類、接口和包的UML類圖表示
類的UML類圖表示
UML類圖中用矩形框表示一個(gè)具體類,矩形框分為三層:
? 第一層:類名
? 第二層:成員變量
? 第三層:成員方法
成員變量以及成員方法名前的訪問修飾符用對應(yīng)符號來表示,成員變量以及成員方法名后緊跟著":"后面再跟著成員變量的類型或者方法的返回類型,舉個(gè)例子。
class Student{
public String pubVar;
protected String proVar;
private String priVar;
String defaultVar;
public String pubFun(){
return "pubFun";
}
protected String proFun(){
return "proFun";
}
private String priFun()
{
return "priFun";
}
String defaultFun(){
return "defaultFun";
}
}下面是該類對應(yīng)的UML類圖:

抽象類的UML類圖表示
抽象類在UML類圖中同樣用矩形框表示,不同的是抽象類的類名以及抽象方法的名字都用斜體字表示,其它和具體類沒有任何差別。
下面是一個(gè)抽象類的定義:
abstractclass Person{
public String pubVar;
protected String proVar;
private String priVar;
String defaultVar;
public String pubFun(){
return "pubFun";
}
protected String proFun(){
return "proFun";
}
private String priFun()
{
return "priFun";
}
String defaultFun(){
return "defaultFun";
}
//抽象方法
publicabstractvoid abstractFun();
}
接口的UML類圖表示
接口在類圖中也是用矩形框表示,但是與類的表示法不同的是,接口在類圖中的第一層頂端會(huì)用 <<interface
下面是一個(gè)接口的定義:
interfaceShoes{
void abstractFun();
}

包的UML類圖表示
package graph;
UML類圖表示類之間關(guān)系
繼承關(guān)系
繼承關(guān)系也稱為泛化關(guān)系,是指對象與對象之間的繼承關(guān)系。如,
在UML類圖中,繼承關(guān)系是用空心三角和實(shí)線組成的箭頭表示,從子類指向父類。
class Parent{
}
class SonextendsParent{
}

實(shí)現(xiàn)關(guān)系
實(shí)現(xiàn)關(guān)系是指接口及其實(shí)現(xiàn)類之間的關(guān)系。在UML類圖中,實(shí)現(xiàn)關(guān)系用空心三角和虛線組成的箭頭來表示,從實(shí)現(xiàn)類指向接口,
interfaceAnimal{
}
class DogimplementsAnimal{
}

聚合關(guān)系
聚合關(guān)系是一種特殊的關(guān)聯(lián)關(guān)系,表示的是整體和部分的關(guān)系,整體與部分具有各自的生命周期,即使整體沒有了,部分還能存在,典型的例子就是,公司部門與員工的關(guān)系,一個(gè)部門撤消了,員工還能存在。
在UML圖中,聚合關(guān)系用空心菱形加實(shí)線箭頭表示,空心菱形在整體一方,箭頭指向部分一方。
class Department{
privateEmployee employee;
}
class Employee{
}

組合關(guān)系
和聚合關(guān)系類似,組合關(guān)系表示的也是整體與部分的關(guān)系,但不同于聚合關(guān)系的是:組合關(guān)系中,整體與部分不可以分開,一旦整體對象不存在,部分對象也將不存在,部分對象與整體對象之間具有同生共死的關(guān)系。
組合關(guān)系和聚合關(guān)系不關(guān)概念很像,它們的UML類圖表示也很像,在UML圖中,組合關(guān)系用實(shí)心菱形加實(shí)線箭頭表示,實(shí)心菱形在整體一方,箭頭指向部分一方。
舉個(gè)例子,比如人的頭(Head)和嘴巴(Mouth),嘴巴是頭的組成部分之一,一旦頭沒了,嘴巴也沒了,因此頭和嘴巴是組合關(guān)系,對應(yīng)的java代碼如下:
class Mouth
{
}
class Head {
private Mouth mouth;
}
依賴關(guān)系
依賴(Dependency)關(guān)系是一種弱關(guān)聯(lián)關(guān)系。如果對象A用到對象B,但是和B的關(guān)系不是太明顯的時(shí)候,就可以把這種關(guān)系看作是依賴關(guān)系。如:工人(Worker)要去擰螺絲,要依賴螺絲刀(Screwdriver)來幫助你完成擰螺絲的工作
依賴關(guān)系在Java中的具體代碼表現(xiàn)形式為B為A的構(gòu)造器或方法中的局部變量、方法或構(gòu)造器的參數(shù)、方法的返回值,或者A調(diào)用B的靜態(tài)方法。
在UML類圖中,依賴關(guān)系用一個(gè)帶虛線的箭頭表示,由使用方指向被使用方,可以看下面的例子。
class Screwdriver{
}
class Worker{
//Screwdriver對象作為Worker類方法的參數(shù),構(gòu)成依賴關(guān)系
public void screw(Screwdriver screwdriver){
}
}

最后,在網(wǎng)上找到一張對于類圖比較綜合的例子(如有侵權(quán),請聯(lián)系我刪除),它將我們前面介紹的內(nèi)容都聯(lián)系起來,如下圖所示,大家可以對照著理解圖中各個(gè)類之間的關(guān)系:

本文源碼地址:
https://github.com/qinlizhong1/javaStudy/tree/master/DesignPattern/src/graph
本文示例代碼環(huán)境:
操作系統(tǒng):macOs 12.1
JDK版本:12.0.1
maven版本: 3.8.4
— 完 —
