圖1 關係
同類的一群物件,除了享有相同的語意、屬性和操作外,最容易被人遺漏的是,它們也享有相同的關係。其實,單獨的類別無法提供太大的功用,必須透過關係連結其他的類別,造成一加一大於二的團結力量,如圖1所示。
結合關係
圖2 參與者與用例之間的結合關係
溫故而知新,是一種很棒的學習方法,不僅可以溫習已知,更可以活用已知,以便進一步獲得新知。這跟物件導向所謂的重用(reuse)的概念,其實是異曲同工的作法。
所以,仔細回想一下,我們在何處學過結合關係呢?想起來了嗎?是的,我們在講解用例圖的元素時,花了一些篇幅談到了參與者和用例之間的結合關係,如圖2所示。
圖3 類別之間的結合關係
還記得我們當時曾說過,結合關係用在用例圖中,價值不大。但是,如果用在類別圖中,就非常重要了,結合關係是類別之間最重要的關係之一,如圖3所示。主因在於:
1. 程序員會按照類別圖直接編寫程式碼,因此物件之間可以透過結合關係呼叫彼此的操作。
2. 再者,如果後端採用關聯式資料庫的話,類別會被實作成資料表,而結合關係則會被實作成資料表之間的關聯。
結合關係擁有許多瑣碎的性質,所幸我們一路學來,很多細小的性質都談過了,所以我們可以繼續往下學習之前沒學過的新概念。
請先打開參與者與用例之間的結合關係性質表,以及類別之間的結合關係性質表,比較一下,其內包含的性質一模一樣,如圖4所示。別忘了,要一併打開模版和角色來檢查一下喔,魔鬼藏在細節中呢!
圖4 結合關係的性質表
由於,程序員會依照類別圖直接按圖施工,所以類別圖中的許多細小性質都可以對應成程式碼中的一部份。不過,我要特別說明的是,UML是一套中立的圖形語言,所以在UML規格書中,並沒有規定程式語言該如何實作UML。這裡所談的實作對應的情況,都只是實務上常見的做法,但不是唯一的做法。
圖5 角色名稱
比方說,結合關係的兩個端點,稱為「角色」(Role)或「結合端」(Association End),如圖5所示。通常,我們不會特別為角色取名稱,可是在實作上有一種做法是,採用角色名稱做為物件名稱,用來保存物件在記憶體中的位址。
其實,角色名稱可以用來標示出物件是以什麼樣的角色參與這個結合關係的,不過如果兩類別之間只有一個結合關係時,通常就不會特別為兩角色命名。但是,如果考慮到實作狀況的話,當然也可以特別為角色命名,方便程序員按圖施工,或者方便軟體工具自動產碼。
許多提供自動產碼功能的UML工具,會依照角色名稱自動產碼。VS2010/UML沒有提供自動產碼的功能,所以我們改看StarUML的示範。
圖6 角色名稱[StarUML]
依照圖6的內容,我們透過圖7的自動產碼功能,分別產出C#程式碼,以及Java程式碼如下所示。你可以仔細看到程式碼中的物件名稱,會發現它們跟角色名稱一模一樣。
圖7 自動產碼[StarUML]
現在,我們回過頭來看角色的性質表,如圖8所示。大部分的性質我們之前都談過了,只有一兩個性質還沒談過,條列如下:
圖8 角色名稱的性質表
● 聚合(Aggregation):
跟聚合和組合有關,稍後我們才會仔細來談這兩者的關連。
● 能見度(Visibility):
基於物件導向的封裝特性,通常我們會將角色的能見度設成私有等級。
● 衍生聯集(Derived Union):
衍生聯集代表聯合兩個已知的集合。兩個集合(Set)的元素合併在一起,重複的元素只算一次,形成一個新的集合,這個新集合就是兩個或數個集合的「聯集」(Union)。比方說,A集合有(1、2、3、4、5),B集合有(4、5、6、7、8),因此A和B這兩個集合的聯集會得到{1、2、3、4、5、6、7、8},如圖9所示。
圖9 聯集
最後,我們來看一下角色密密麻麻的性質到底出現在UML母模中的何處?如圖10所示。
圖10 角色[UML母模]
聚合關係
圖11 聚合關係
聚合關係(Aggregation)是一種特別的結合,它是一種「整體-部分」(Whole-Part)的結合關係。因此,聚合關係的圖示跟結合關係一樣,採用實線連接兩類別,不過會以小的空心菱形標示出整體端,如圖11所示。
由於,聚合關係只比結合關係多了一個整體—部分的意涵,所以它並不是一項全然不同的嶄新關係。請你看到聚合關係的性質表,它的名稱其實還是結合關係,只是在整體端的「聚合」(Aggregation)的欄位中,出現「共有」(Shared),如圖12所示。
圖12 聚合關係的性質表
組合關係
圖13 結合、聚合和組合
你剛才一定注意到了,在結合關係性質表的聚合欄位中,有三個選項,如圖13所示,最後一個就是組合關係。
圖14 組合關係
聰明的你一定推想到了,組合關係如同聚合關係,其實它們都是一種特殊的結合關係,而且它們都具有「整體—部分」意涵。組合關係中的整體端,採用小的實心菱形來標示出,如圖14所示。
我想,從聚合性質的名稱處,可以容易區分出聚合關係和組合關係兩者的不同之處,如下:
● 組合關係是一種構成或合成的整體-部分關係,部分是整體的重要構成元素之一。所以,整體物件將全權擁有部分物件,不會與其他整體物件共有同一個或一些部分物件。
● 但是,聚合關係就不同了,它沒有組合關係這麼強烈。聚合關係是一種可以共有的整體—部分關係,所以多個整體物件可以共有同一個或一些部分物件。
繼承關係(一般化)
前面我們已經說過,在程式語言或者VS2010/UML中的「繼承關係」(Inheritance),在UML中稱之為「一般化關係」(Generalization)。也就是說,在UML中,並沒有繼承關係,只有一般化關係,特別提醒你一下。
在VS2010/UML中,這兩個詞彙似乎是混用的,譬如在用例圖中採用一般化關係,但在類別圖處,確又改採用繼承關係。我的推想,可能是因為程序員可以直接依照類別圖按圖編碼,所以乾脆採用程式語言慣用的繼承關係。
然而,在用例圖中,因為偏向表達問題領域(problem domain)的概念或現象,所以保留原先的一般化關係,會比較貼近問題領域的用語。
因此,這一系列文章中,大部分情況我們會使用「一般化關係」這個字眼,以便保持跟UML的一致性。但是,如果提到VS2010/UML時,會視VS2010的情況混用「繼承關係」和「一般化關係」。
此處,我想特別提一個容易被忽略的特性,一般化關係其實是一種類別之間的關係。相較之下,前述的結合/聚合/組合關係,則是一種個體(instance)之間的關係。
雖然,兩種關係的圖示在類別圖面上,都放置在類別圖示之間、連接了兩類別圖示。但是,它們在本質上,一般化關係是類別之間的關係,而結合/聚合/組合關係是個體(物件)之間的關係。請你看到圖15的UML母模,可以說明這一項特別的性質。
圖15 結合/聚合/組合關係是個體之間的關係[UML母模]
先看到圖15,結合關係的兩端連接的是「性質」(Property),而性質正是一種具有型別的元素。最常見的性質實例,就是我們所謂的個體(instance)。再看到圖16中,一般化關係的兩端所連接的是「類詞」(Classifier)。最常見的類詞實例,就是我們常說的類別。
圖16 一般化關係是類別之間的關係[UML母模]
回過頭來談一般化關係的概念,其實簡單易懂。一般化關係指出了一般類別,和這個一般類別底下的特殊類別。每一個特殊類別所誕生的個體,都是其一般類別的間接個體。也因此,特殊類別繼承了一般類別的特徵,包含有:意涵、屬性、操作和關係。
比方說,在圖17的例子中,因為學員繼承了訪客,所以學員不需要額外宣告暱稱、訂報、電郵這三個屬性,以及取消訂閱和訂閱電子報這兩個操作,直接繼承訪客定義好的屬性和操作來用就可以了。
圖17 一般化關係
有時候,特殊類別需要重新定義繼承而來的操作時,可以選擇「覆寫操作」(Override Operations),如圖18所示。
圖18 重新定義操作
在VS2010/UML中,一旦我們勾選了想要重新定義的操作之後,在特殊類別處,就會出現剛才勾取的操作,可以讓我們重新定義。
圖19 勾選訂閱電子報
圖20 重新定義訂閱電子報
一般來說,如果沒有需要重新定義時,特殊類別不會顯示出繼承而來的操作。請你看到圖19和圖20的範例,我們勾選了訂閱電子報,然後再重新定義時加上了「訂閱日期:Date」這項參數。
專欄作者
熱門新聞
2024-12-27
2024-12-24
2024-11-29
2024-12-22
2024-12-20