UML基礎知識
目錄
(這個是很久以前寫的一篇關於UML的文章,現在放出來和大家共享)
瞭解一下類與類之間的關聯基礎知識很有必要,因為這些關係就像我們建造房子的基石,是面向對向程式設計的基礎。
類中的關係有六種,分別是關聯(Association)關係、聚合(Aggregation)關係、組合(Composition)關係、泛化(Generalization)關係、實現(Realization)關係以及依賴(Dependency)關係,下面分別介紹這六種關係。
依賴(Dependency)關係
依賴是物件之間最弱的一種關聯方式,是一種臨時性的關聯,依賴物件依賴於被依賴的物件來完成某方面的功能,被依賴物件行為的改變會影響的依賴物件的結果輸出,程式碼中一般指由區域性變數、函式引數、返回值建立的對於其他物件的呼叫關係。
在類圖使用帶箭頭的虛線表示,箭頭從使用類指向被依賴的類,如下圖示:
比如某個人吃飯要使用到勺子,此時人和勺子之間就是一種依賴關係,勺子的大小會影響到人吃飯的速度或者心情等,此時的依賴關係圖如下:
關聯(Association)關係
關聯表示的是兩個物件之間的關係,換句話說,關聯定義了物件之間的多重性,關聯關係是一種比依賴關係更強的關係,不存在依賴關係的偶然性、關係也不是臨時性的,一般是長期性的,而且雙方的關係一般是平等的、關聯可以是單向、雙向的,我們經常用到的關聯有一對一、一對多、多對一、多對多,它們之間的表示方式是用一條直線箭頭連線,箭頭所指的方向為被依賴的物件:
單向的關聯關係
雙向的關聯關係
箭頭兩端的數字,分別表示兩個關聯物件之間的數量關係,下面分別舉例說明。
一對一
如妻子與丈夫的關係,一個妻子只會有一個合法的丈夫,一個丈夫只會有一個合法的妻子,它們體現的是雙向的關聯聯絡,可以用如下圖示表示:
一對多、多對一
如一個公司會有多名員工,多名員工會同屬於同一個公司,此時從公司的角度看和員工的關係,就是一對多的關係,如果從員工的角度看和公司的關係,那就是多對一的關係,用如下圖示表示:
多對多
如一個專業的攝影師會和多家報社簽約,以便於這些報社都可以使用TA的照片,而同時每家報社又會和不同的攝影師進行簽約,也就是每家報社都會有多名簽約攝影師,這種關係就屬於多對多的關係,可以用如下圖示表示:
聚合(Aggregation)關係
聚合關係也是關聯關係的一種,不過它表示的是一種更強的關聯關係,它用來表示整體和部分之間的關係,表示物件與物件之間直接的關係,當一個物件“擁有”另外一個物件時,它們之間就可以使可以使用聚合關係,因而聚合關係也通常被稱為“擁有”關係。
聚合關係用空心菱形+實線+箭頭圖示表示,菱形的一邊指的的擁有者,實線所在的一邊為被擁有者:
箭頭兩端的數字,分別表示兩個關聯物件之間的數量關係,下面分別舉例說明。
一對一
每輛汽車都會有引擎,而每一輛汽車通常來說都只會有一個引擎,這裡的場景就適合於使用聚合關係圖示表示:
一對多、多對一
汽車能夠開走,那沒有輪子肯定是不行的,也就是說汽車擁有輪子,並且通常的汽車都有四個輪子,他們也適合於用聚合關係表示:
汽車有一個引擎,也有四個輪子,他們之間的關係使用如下圖表示:
多對多
組合(Composition)關係
組合關係是一種特殊的聚合關係,但是它比具有聚合關係具有更強的關係,當一個物件中包含另一個/些物件,如果沒有容器物件的存在,那麼被包含的物件就不能夠存在時,此時這種關係就稱為組合關係;組合關係中要求代表整體的物件負責對代表個體/部分的物件的整個生命週期的管理,如果代表整體的物件被銷燬/破壞,那麼代表個體/部分的物件也一定會被銷燬/破壞。
聚合關係和組合關係的差別就是,在聚合關係中代表個體/部分的物件則有可能被多個代表整體的物件所共享,而不一定會隨著某個代表整體的物件被銷燬/破壞而被銷燬/破壞。
組合關係用實心菱形+實線+箭頭圖示表示:
箭頭兩端的數字,分別表示兩個關聯物件之間的數量關係,下面分別舉例說明。
一對一
通常來說我們每個人的頭上都只會有一個嘴巴,一個嘴巴只會屬於一個頭,如果頭沒有了,那麼嘴巴也就沒有了,頭必須為嘴巴的存在負責,他們符合組合關係的定義,並且是屬於一對一的關係,可以用如下圖示表示他們之間的組合關係:
一對多、多對一
我們的每隻手,都會有五個手指,手指必須存在於手上,如果手沒有了,那麼手指也就不存在了,他們的定義符合組合關係的定義。一隻手可以有多根手指,此時以手做為主體,那麼手和手指的關係就是一對多的關係,如果是以手指為主體,多根手指同時屬於一隻手,此時就是多對一的關係。圖示如下表示:
多對多
在真實的世界中,雖然多對多的組合情況是存在的,如一對連體姐妹,他們是兩個人,但是他們只有兩隻腳,兩個人都可以對腳進行支配,腳是屬於兩個人的,這種情況也是屬於多對多的組合情況。
但是在我們的系統中,多對多的組合關係是存在的嗎?
泛化(Generalization)關係
泛化表示的是is-a的關係,是物件之間耦合度最大的一種關係,子類繼承父類的所有細節,並具有可以增加它自己的新功能的能力,繼承是類與類或者介面與介面之間最常見的關係,在Java中直接使用語言中的繼承關鍵字extends明確標識。
UML類圖中使用帶三角箭頭的實線表示,箭頭從子類指向父類,如下圖示:
類與類之間的繼承
介面與介面之間的繼承
一個子類只可以繼承一個父類,因為繼承了父類的子類,只可以是父類的的某一種特殊型別,例如我們人類,只可以是動物或者植物中的一種,不可能既是動物又是植物,此時的繼承關係圖如下:
但是介面之間的繼承,子介面是可以同時繼承多個父介面的,因為介面之間的表示的是功能或行為之間的繼承,如我們人類可以有多種行為,如吃飯、睡覺、走路等,每一種行為可以用一個父介面表示,此時的繼承關係圖示如下;
實現(Realization)關係
實現關係在類圖中表示的就是介面和實現類的關係,指的是一個class類實現一個或多個介面的功能,也是非常常用的關係,在Java中直接使用語言中的實現關鍵字implements明確標識。
UML類圖中使用帶三角箭頭的虛線表示,箭頭從實現類指向介面,如下圖示:
一個子類可以實現多個介面,這個可以理解為子類具有了被實現的父類的所有功能,子類可以同時實現不同的父類來具有不同的功能,如人有吃東西這麼一種功能,也可以有走路這樣的功能,還可以有說話的功能等等,此時的實現關係圖如下:
總結:
這六種關係中,繼承和實現體現的是一種類與類、或者類與介面間的縱向上下級關係;而組合、聚合、關聯及依賴這四者關係則體現的是類與類、或者類與介面間的橫向引用關係,有些時候比較難以區分,並且有很多事物間的關係要想準確定位也不容易,這幾種關係都是語義級別的,所以從程式碼層面並不一定能夠完全區分這幾種關係;但總的來說,組合、聚合、關聯及依賴這幾種關係所表現的依賴強弱程度依次為:組合>聚合>關聯>依賴。