類的UML圖表示
在UML類圖中,類使用包含類名、屬性和方法且帶有分隔線的長方形來表示,請看下圖使用類圖表示類信息的示例:
我們通常將類圖表示的類分為三個部分:
第一部分為類名,如果類名用正體書寫則說明這是可以實例化的普通類。如果類名用斜體書寫,則說明這是抽象類。如果類名有下劃線修飾則說明這是靜態類。
第二部分為類屬性,格式為修飾符屬性名 :屬性類型。修飾符為「+」說明該屬性為public型,「#」說明該屬性為protected型,「-」說明該屬性為private型。
第三部分為類方法,格式為修飾符方法名 (參數名1:參數類型1,……):方法返回值類型。修飾符為「+」說明該方法為public型,「#」說明該方法為protected型,「-」說明該方法為private型。如果方法名有下劃線修飾則說明這是靜態方法。
UML類圖模型元素
在UML類圖中一共包含三種模型元素,分別是:類(Class)、接口(Interface)以及類之間的關係。我們在上述People類圖的基礎上來說明這三種模型元素,將會更加直觀,請見下圖:
UML類圖關係
在UML類圖中,最重要的就是類圖之間的關係,顧名思義就是通過類圖的方式把類與類之間的關係表述清楚。面向對象的編程中,類與類之間關係通俗點講就兩大類關係,一類是我中有你,你中有我的關係,另一類是父與子的關係,個人喜歡將其分為橫向關係和縱向關係,橫向就是依賴和關聯,縱向就是泛化和實現,其中聚合和組合也屬於特殊的關聯關係。
泛化關係:
定義:表示類與類之間/接口與接口之間的一種繼承關係,指定了子類如何特化父類的所有特徵和行為
表示方式:使用帶三角箭頭的實線表示,箭頭指向父類
示例:老虎是動物的一種,老鷹是動物的一種,動物都有Move方法,但是老虎和老鷹的Move是有差異的,老虎是奔跑,老鷹是飛翔。
實現關係:
定義:表示類是接口所有特徵和行為的實現,也是一種繼承關係,是指類對接口的實現。
表示方式:使用帶三角箭頭的虛線表示,箭頭指向接口類。
示例:滑鼠事件的監聽接口類,Button控制項實現該接口類,ListView控制項實現該接口類,那麼Button控制項類和ListView控制項類都是滑鼠監聽事件的實現類。
依賴關係:
定義:對於兩個相對獨立的對象,當一個對象負責構造另一個對象的實例,或者依賴另一個對象的服務時,這兩個對象之間主要體現為依賴關係。我們可以將依賴關係理解為一種使用的關係,也就是「Use-a」的關係,我們在設計類時,儘量避免雙向的互相依賴。
表示方式:帶箭頭的虛線,指向被使用者或者被創建者
示例:做地鐵上班,依賴地鐵的服務;使用螺絲刀將螺絲擰緊,依賴螺絲刀;駕駛員開車,依賴汽車;這些都是典型的依賴關係。依賴關係通常通過三種方式來實現:
1) 某個類的方法使用另一個類的對象作為參數
2) 在一個類的方法中將另一個類的對象作為其局部變量
3) 在一個類的方法中調用另一個類的靜態方法
再簡單一點理解,類 A 使用到了類 B,並且這種使用關係具有偶然性,臨時性,是非常弱的關係,但是 B 類中的變化會影響到類 A。比如,班車司機每天開著班車接送公司員工上下班,每天班車可能不同,但是班車司機只是一個司機,公司給配哪輛班車,司機就是使用哪輛班車接送員工。
關聯關係:
定義:對於兩個相對獨立的對象,當一個對象的實例與另一個對象的一些特定實例存在固定的對應關係時,這兩個對象之間為關聯關係。關聯關係體現的是兩個類一種強的依賴關係,不存在依賴關係中的偶然性,關係也不是臨時的,一般是長期性的。可以理解為一種擁有或者對應關係,我們也稱作為「Has-a」的關係。再直白點講,其實所謂的關聯就是某個對象會長期的持有另一個對象的引用,而二者的關聯往往也是相互的。關聯的兩個對象彼此間沒有任何強制性的約束,只要二者同意,可以隨時解除關係或是進行關聯,它們在生命期問題上沒有任何約定。被關聯的對象還可以再被別的對象關聯,所以關聯是可以共享的,並且關聯關係可以是單向的,也可以是雙向的。
單向關聯表現為:
類 A 當中使用了類 B,其中類 B 是作為類 A 的成員變量。
雙向關聯表現為:
類 A 當中使用了類 B 作為成員變量,同時類 B 中也使用了類 A 作為成員變量。
表示方式:單向關聯,使用帶普通箭頭的實心線表示,指向被擁有者
雙向關聯,可以使用有兩個箭頭或者沒有箭頭實心線表示
示例:員工和公司,員工屬於某個公司,公司有多個員工;訂單和客戶,訂單屬於客戶,客戶可能有多個訂單;車主人和車,車屬於車主人,車主人可以擁有多輛車,其實上述依賴關係的類圖稍加修改,即可變成關聯關係。
聚合關係:
定義:屬於關聯關係的一種,耦合度強於關聯,他們的代碼表現是相同的,僅僅是在語義上有所區別,關聯關係的對象間是相互獨立的,而聚合關係的對象之間存在著包容關係,他們之間是「整體-個體」或者「整體-部分」的相互關係,且部分可以離開整體而單獨存在。聚合關係是比關聯關係更親密的一種關係。
表示方式:帶空心菱形的實心線,菱形指向整體。
示例:我們還是以車為例,比如車和輪胎,輪胎離開車可以單獨存在,車和發動機,發動機可以離開車單獨存在。其實上述司機和汽車的關係稍加修改就可理解為聚合關係。通過Set接口來設置這個司機具體開哪個車,可以理解為整體和個體的關係,車也可以脫離司機而單獨存在。
組合關係:
定義:是比聚合關係還要強的關係,它要求普通的聚合關係中代表整體的對象負責代表部分的對象的生命周期,即「整體」負責「部分」的生命周期,他們之間是共生共死的,並且「部分」單獨存在時沒有任何意義。
表示方法:帶實心菱形的實線,菱形指向整體
示例:比如公司事業部BU與公司的關係,如果公司不存在了,那麼事業部BU就失去了單獨存在的意義。其實還是以上述司機和汽車的例子來說明,只不過此時我們司機和汽車的意義和之前不太一樣,我們先看類圖,再來解釋其意義,看看是不是屬於組合關係。
我們這樣理解這個類圖:
Car作為Driver財產屬性的一部分;
Car是Driver必須要有的財產,要想成為Driver必須要有Car,而且Car要是沒了,Driver悲傷欲絕,也輕生了。而且Driver要是開車了,Car也就沒了。
UML類圖總結
各種類關係強弱順序總的來說繼承大於關聯,關聯大於依賴,具體強弱順序如下:泛化 = 實現 > 組合 > 聚合 > 關聯 > 依賴。
通常關聯、聚合、組合只能配合語義,結合上下文才能夠判斷出來,只給出一段代碼,通常是無法判斷的。
我們要明白不是為了學類圖而學類圖,所以我們在掌握類圖的表達形式後,應該多多實踐和理解,與實際項目關聯起來,收穫才會更多。
我們一定要熟記類圖關係的表示方法,這樣我們在自己畫類圖或者看別人類圖時,才能遊刃有餘,並且不會出現理解偏差。
UML類圖實踐