關聯指兩個類之間的各種聯繫。UML使用各種單實線表示關聯,這個單實線可以是直線(垂直的、水平的或者傾斜的)、折線甚至曲線。
事實上,關聯也是展示類的屬性的另一外的一種形式。例如在下圖中,我們通過一條實線連接類Book和類Person,表示它們之間存在關聯。在關聯的末端,標出多重性[*]和關聯端名稱(通常稱為“角色名稱”)author。
從上圖中我們可以看到關聯端名稱(角色名稱)author是類Book的一個屬性。
在上圖中,類Book的屬性author在類Book的屬性描述中和關聯的角色名稱中同時出現了。一般情況下,我們不會同時使用這兩種形式,它可能會帶來混淆並且帶來了冗餘,故可將上圖中類Book的屬性author刪除掉,以下圖的形式表示即可。
上圖有兩種解讀方法:
一本書(Book)有多位作為作者(author)的人(Person)。
或
一本書(Book)有一組由多個人(Person)組成的作者(author)。
1.屬性和角色修飾符
在類圖中,我們可以為屬性添加一些修飾符以表達對屬性的約束。類屬性的表達方式與角色名稱的表達方式都是表達源端類的屬性信息的手段,故在使用角色名稱時,同樣也可以通過修飾符對角色名稱進行約束。
例如在下圖中,我們為角色名稱author添加ordered和readOnly屬性。這些屬性被包含在一對大括號中(大括號表示約束)。
此時,上圖可以解讀為:
一本書(Book)有一個由多個人(Person)組成的只讀的、有序的作者(author)集合。
或
一本書(Book)有一個由多位擔任作者(author)角色的人(Person)組成的只讀的、有序的集合。
我們幾乎可以將能賦予屬性的所有內容都賦予關聯端。下表展示了屬性幾乎所有可用的修飾元素。
在表格中,給出了這些修飾元素的符號表示以及其多重性,即該符號可以出現的次數。0..1表示這是一個可選符號;0..*表示該符號可以根據需要出現多次。表格中各表示元素的順序也是它們在表示時所應採取的大致順序。
注:上述表格是不完整的,但它已經覆蓋了大多數情況。
而下表則是關聯端(角色名稱)可以使用的修飾元素,在這個表格中也給出了修飾元素的符號表示以及其多重性,同時也給出了使用修飾符時其所處的位置。
關聯具有表徵類與其屬性之間關係雙向性的優勢。當屬性是一個類(而非數據類型)時,使用關聯形式最為常見。各個類(或數據類型)可以進一步與類相連接,而圖表則展示了它們之間關係的更完整圖景。
當然,一個類也可以同時與多個類產生關聯。例如對於類Person,它既可以是類Book的author,也可以是Score的composer,此時這兩個關聯可以用下圖進行表示。
2. 解讀關聯
在上述説明中,我們由類Book關聯到類Person、由類Score關聯到類Person。但關聯是兩個相關類的關係,故而也應當可以由類Person關聯到類Book、由類Person關聯到類Score。因此,我們也可以考慮在關聯的另一端提供關聯端裝飾。
在下圖中,同時給出了兩個方向的關聯信息。
上圖中的關聯的可以分別解讀為如下:
- 一本書(Book)有一個由多個人(Person)組成的有序的作者(author)集合。
- 一個人(Person)有一個由多本書(Book)組成的我的書籍(myBooks)集合。
- 一個樂譜(Score)有一個由多個人(Person)組成的有序的作曲家(composer)集合。
- 一個人(Person)有一個由多個樂譜(Score)組成的我的樂譜(myScore)集合。
當閲讀一個關聯關係時,從一側開始(源側),但只讀另一側(目標側)上的修飾符。目標側是遠離開始端的那一側,源側是靠近開始端的那一側。
請特別注意,上述關聯中所涉及的名稱是關聯端(角色)名稱,而關聯關係本身也可以擁有名稱,關聯關係的名稱獨立於兩端的關聯端名稱(角色名稱),也獨立於兩端類或類型的名稱。這些名稱通常使用動詞形式,例如下圖中所使用的名稱是“is authored by”。當為關聯提供名稱時,通常採用從左向右或者從上到下的形式書寫。
在閲讀一個關聯關係時,總是以“一個”“某個”“每個”或類似的詞開始,多重性只在目標側讀取,而源側的多重性和修飾符被忽略掉。
上圖是對從一本書(A Book)到多個人(many Persons)以及從一個人(A Person)到多本書(many Books)的關係進行建模。這種解讀是基於關聯關係與屬性之間的等價性。由於屬性僅是實例的屬性,因此目標側的關聯端點也僅是實例的屬性。
Book --> Person:一本書(Book)由多個人(Person)組成的有序的作者(author)[集合]所著。
當你反向閲讀時,通常需要將動詞形式從主動語態改為被動語態,或者反之。
Person --> Book:一個人(Person)有一個由多本書(Book)組成的我的書籍(myBooks)[集合]。
在下圖中,關聯被命名為“authors”,這是“to author”現在時第三人稱主動形式。當反向閲讀時,則需要使用被動形式“is authored by”。這裏我們使用了另一種表示法,即使用了閲讀方向指示符►或◄,這個三角形指示了關聯名稱預期的閲讀方向。這個指示符在繪製圖表(如改變關聯方向)時很有用,但由於它可能需要手動維護三角形的方向而增加了困難。
下表給出了關聯關係所可能使用的屬性及其説明。
![]()
回顧上述説明,我們可以發現其實兩個類之間可以存在多個關聯,例如上例中,Person既可能是Book的author,也可能是Book的editor。此時可以描述兩個關聯關係,並分別描繪其關聯端名稱(角色名稱)及關聯名稱等信息。但要注意的是,角色名稱會被映射為屬性名稱,受限於在同一個類的命名空間中不允許有兩個同名屬性的規定,在兩個類之間存在多個關聯時其角色名稱也不可以重複。但在使用工具描繪關聯時,角色名稱可以為空,此時工具會為它們生成不透明的不同名稱。
3. 關聯和數據類型
正如我們上文所討論的,可以將屬性表示為關聯。在前述示例中,我們討論了類型為類(例如Book、Person或Score)的屬性及其工作方式。當屬性為數據類型時,通常只對從源類到目標數據類型的單向關聯建模,除此之外,其他都基本相同。另外,在目標是數據類型的情況下,一般也不會使用關聯名稱。例如,對於Book的pages屬性而言,可以通過下圖所示的關聯表示。
4. 鏈接和實例
前文關聯都是在類圖中進行描繪,在對象圖(實例圖)中,也有類似的場景。我們只需使用實例代替類,用鏈接代替關聯即可,如下圖所示。
按UML規範,實例名稱會帶有下劃線,實例之間的鏈接名稱也應帶有下劃線,但與實例名稱不同,鏈接名稱的下劃線是可以省略的。
特別提醒一點,鏈接上是不會顯示多重性的,因為在對象圖的鏈接中每一側總是隻有一個實例,多重性需要通過對多個實例建立多條鏈接來體現。
