天天看點

《軟體方法》第8章 分析 之 分析類圖(3)

8.2.3 識别關聯關系

8.2.3.1 關聯的三種形式

UML規定了關聯的三種形式:普通關聯、聚合(Aggregation)群組合(Composition)。

說到這裡,我們有必要歸納類的關系如圖8-90。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-90 類的關系

有些書和文章裡提到“泛化群組合”,其實是不合适的,因為泛化群組合不在一個抽象級别上。說“泛化和關聯”可以。

在圖形表示上,普通關聯是一根直線,聚合的整體一端是空心菱形,組合的整體一端是實心菱形。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-91 三種關聯的圖示

當然,更重要的是意義不一樣。之是以分出聚合/組合這樣的特殊關聯,考慮的出發點是責任配置設定。通過建立聚合/組合,使整體把部分封閉起來。在責任配置設定時,不管外部對象想要發消息給聚合/組合結構裡的哪一個對象,都應該先把消息發給整體對象,再由整體對象分解和配置設定給聚合/組合裡的對象,如圖8-92所示。

《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

圖8-92 聚合/組合關聯影響責任配置設定

類圖上會有很多類,類之間關系的密切程度不一樣。有些類互相之間關系更密切,當推斷或觀察到這些類之間的協作的頻率遠超過它們和外部其他類的協作頻率時,通過聚合/組合來封裝它們是合算的,因為這樣可以大大減少外部對這些類調用的複雜度。

引入聚合/組合,相當于把類圖分區,每個區找一個區長作為責任配置設定的起點。這是一項十分重要的分析技能。例如圖8-93就是一張餐飲領域的類圖,可以看出右上角“顧客”分區的領域概念和左上角“餐台”分區的領域概念所受的影響因素應該有較大差别。

聚合/組合和公司的部門劃分類似。公司不劃分部門,老總一個個員工派任務也能達到目标,隻是效率不高,而且不管出現什麼改變都要打開老闆的“代碼”來修改。分了部門之後,老闆就爽多了,隻需要和部門經理打交道。當然,分部門也不能亂分,否則效果還不如不分。如果公司分了部門之後發現部門内部員工之間互動甚少,反倒是串門的很多,那很可能公司的部門分割是亂點鴛鴦譜了。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-93 餐飲領域類圖分區

上面關于責任配置設定的描述,對于聚合群組合都是合适的,是以表達時使用的是聚合/組合。那麼,聚合群組合的差別是什麼?

組合可以看作是更強的聚合,相對于聚合來說,組合還要滿足以下要求:

(1)整體對象被銷毀,部分對象也要銷毀;

(2)部分對象隻屬于一個整體對象;

(3)整體對象負責部分對象的建立和銷毀。

也就是說,部分對象隻應該作為整體對象的一部分存在,不應獨立存在,是以部分類的命名往往有整體類的味道,如圖8-94所示,“訂單”和“訂單項”之間的關聯是組合,但接下來的“訂單項”和“商品”之間的關聯不是組合;同樣,“報告”和“報告稽核”之間的關聯是組合,但接下來的“報告稽核”和“人員”之間的關聯不是組合。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-94 部分類的命名有整體類的味道

如果暫時無法确定聚合還是組合合适,那麼可以先通通模組化為聚合或組合,後面有足夠證據時再修改。

聚合/組合務必慎用。如果沒有足夠的證據,應該先模組化為普通關聯。有的模組化人員懶得給普通關聯想合适的名字,幹脆一概以“有”稱之,例如“訂單有顧客”,然後得到錯誤的聚合/組合關系,如圖8-95所示。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-95 錯誤的聚合/組合關系

8.2.3.2 識别關聯的思路

之前在審查類和屬性時,“屬性要直接描述類”和“屬性在領域内不可分解”這兩種審查已經演變出了一些關聯關系。

接下來識别關聯也沒有什麼妙招。和識别泛化一樣,嚴格的做法同樣是針對每兩個類以及每個類自身思考系統是否要維護類和類之間的關聯。如果需要,再思考是否有明顯的證據判斷其為聚合/組合,然後再考慮多重性、關聯名、角色名。

這樣做也同樣有工作量巨大的問題,是以一般來說隻需要憑借對領域的了解,迅速定位最應該建立的關聯。如果有遺漏,後面畫分析序列圖時也會發現。

和泛化不同的是,關聯不隻是發生在不同的類之間,還可以發生在同一個類上,即自反關聯。自反關聯對于簡化模型很有幫助,後文會專門講述。為什麼沒有自反泛化?請讀者自行根據前文知識思考。

8.2.3.2.1 關聯是系統維護的關系

萬事萬物之間如果想找關系,總能找到關系的,但所研究系統需要關注的隻是千萬關系中的一小部分。隻有所研究系統負責維護的關系,才有資格變成關聯。

“8.1.6.4 切勿照貓畫虎”裡已經提到這個問題。很多表面上看到的“關聯”,其實不是系統要維護的或者重點維護的關聯。真正重要的關聯往往埋在底下,沒有一定的抽象能力很難發現。如圖8-96所示,分析時不僅僅要看到生機勃勃的綠葉,更要思考這生機勃勃的根源。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-96 葉和根

“8.1.6.4 切勿照貓畫虎”中的圖8-52說系統不需要記住哪個顧客查詢過哪件商品,是以“顧客”和“商品”之間沒有關聯。如果系統确實要維護查詢的資訊,兩個類之間的關聯當然可以存在,不過未必是直接關聯,很可能是像圖8-97。常見的電子商務系統中,需要維護的應該是圖8-97上部的三個類:顧客、查詢和查詢條件,這樣顧客可以反複使用之前設定過的查詢條件。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-97 顧客和商品之間的查詢

8.2.3.2.2 關聯名或角色名

如果問一位習慣于資料庫模組化的模組化人員“A和B是什麼關聯”,可能會得到這樣的回答“是一個一對多的關聯”,因為他覺得說出關聯兩端的多重性就足夠詳細了。

在類模組化中,關聯的名字和角色的名字是很重要的。除非某個關聯的名字已經一目了然,不會造成誤解,否則應該盡量加上關聯名或角色名,這樣模型更能夠講出領域的故事。如圖8-98,關聯名和角色名串起幾個類的概念,生動地展示了領域知識。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-98 模型要能講故事

至于采用關聯名還是角色名來描述關聯,如果角色名更能說明問題,那麼角色名優先。因為角色名在實作中往往會映射為變量名。特别是當兩個類之間有多種關聯的時候,通過角色名區分是必須的。如圖8-99所示。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-99 兩個類之間有多種關聯

聚合/組合關聯經常被認為不需要關聯名或角色名,其實也是需要的。如圖8-100。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-100 聚合/組合的角色名

如果是給關聯命名,最好給名稱添加一個閱讀方向,如圖8-101所示,方向訓示領域知識為“訂單産生結彙單”。不過要注意,這個閱讀方向隻是為了友善了解領域知識,和關聯的導航方向沒有關系。有的模組化工具不支援标注關聯方向,可以通過統一偏向某一側來表達閱讀方向。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-101 關聯名稱的閱讀方向

8.2.3.2.3 導航方向

關聯可以是雙向的,兩端的對象都可以通過關聯導航到另一端;關聯也可以是單向的,隻有其中一端能通路另一端。

注意圖形的表達:一個箭頭都沒有并不是指兩端都不可以導航,而是指兩端都可以導航,相當于兩邊都有箭頭,如圖8-102所示。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-102 關聯導航圖示

一開始對模型的内涵把握不到位,可以保留雙向關聯,但随着對領域内涵的深入了解,應該盡可能把關聯改為單向關聯。這樣可以從根源上防備循環通路和調用。

關于确定關聯的方向原則,我們先來看看常被讨論的人和狗的例子。如圖8-103,日常生活中我們可以說人養了寵物狗,也可以說狗有主人,假設系統要記住人和狗的關聯,哪一個更合适呢?

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-103 人和狗的關聯方向

如果人和狗都是哺乳動物,地位差不多不好判斷,我們可以把問題往極端推,就可以看得更清楚。如圖8-104,人有一個屬性姓名,類型為字元串,圖中左右兩側是等同的。顯然“人”知道“string”是合理的,但是背後的原因不是人比字元串更“複雜”(8.1.6.7已經講述過這個問題),而是系統很可能更關心人的狀态變化。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-104 人和字元串的關聯方向

回到圖8-103。是人知道狗還是狗知道人,判斷的原則是看系統更關心誰的狀态,關心誰,誰就應該知道得越多。不能武斷地說系統一定更關心人的狀态,是以人應該知道狗。也許系統是一個狗舍管理系統,也許系統是一款狗的遊戲——以前還有一款奇葩遊戲叫《壞蟑螂(Bad Mojo)》呢,主角就是一隻蟑螂。

了解了這一點,我們再來看看圖8-105的關聯,“機關”和“裝置”,誰知道誰?在沒有足夠上下文資訊的情況下很難判斷,但如果說系統是一個監測系統,目的是定期了解哪些裝置過期未檢驗,“裝置”的狀态比“機關”的狀态豐富,是以圖8-105下部更合适。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-105 機關和裝置的關聯方向

這裡的判斷原則和關系資料庫模組化有的時候是沖突的。資料庫模組化中,哪個表中有另一個表的辨別,判斷原則是多重性。如圖8-106,類圖中“訂單”知道“訂單項”,但映射到關系資料庫表,“訂單項”表中有“訂單ID”。

《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

圖8-106 關聯導航方向和關系資料庫不一緻

當然,有時也不沖突,圖8-105下部的兩個類就是一緻的。一個機關安裝了多台裝置,映射到關系資料庫,“裝置”表中有“機關ID”。

8.2.3.2.4 多重性

多重性表示關聯兩端允許的對象的數量,可選的表達如圖8-107。

表示 含義
1 1
0..1 0到1
* 0到多
1..* 1到多
具體數字如2..8 2到8

圖8-107 可選的關聯多重性

很多模組化人員糾結于“1”還是“0..1”好,“*”還是“1..*”好,過早分散了精力。先統一使用“1”(涵蓋“1”和“0..1”)和“*”(涵蓋“*”和“1..*”)就可以,等到有更清晰的認識以後再考慮是否改為“0..1”或“1..*”。

對于多重性,模組化人員容易出現的問題是把不同時間的對象快照合并成一個。例如,男人和女人可以有夫妻關系,那夫妻關系的多重性是多少?中國是一夫一妻制度,按道理應該1對1,如圖8-108左側。但有的模組化人員會想,不對呀,有的人一生結好幾次婚,那不是有幾個配偶嗎?是否應該如圖8-108右側?

《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

圖8-108 夫妻關聯的多重性

圖8-108左側是正确的。在任何時間拍攝快照,拍到的應該是一個男人最多和一個女人有夫妻關聯。即使有其他女人,當時的夫妻關聯應該已經斷開了,如果要表達關聯,隻能叫“前妻”。如圖8-109所示。在某個時間拍快照,是有可能拍到一個男人存在多個前妻的。

《軟體方法》第8章 分析 之 分析類圖(3)

圖8-109 一個男人存在多個前妻

8.2.3.2.5 自反關聯

當關聯的兩端是同一個類時,這個關聯就是自反關聯。

根據多重性的不同,自反關聯可以表達不同的形狀,如圖8-110所示。

多重性 對象圖形狀 類圖例子
*對* 網 
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
1對* 樹 
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
1對0..1 隊列 
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
1對1 環 
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

圖8-110 不同多重性的自反關聯

自反關聯對簡化模型很有幫助。在許多分析模式和設計模式中,都可以看到自反關聯。例如,當類結構中的泛化層次很深時,就可以通過把泛化結構轉為更進階抽象的自反關聯,如圖8-111所示。

《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

圖8-111 自反關聯簡化模型

關于自反關聯,本書後文關于分析模式的内容中會有更詳細的講述。

《軟體方法》第8章 分析 之 分析類圖(3)

掃碼或通路http://www.umlchina.com/book/quiz8_2_1.htm完成線上測試,做到全對以獲得答案。

《軟體方法》第8章 分析 之 分析類圖(3)

1. 類之間的關系有

A 擴充、包含、泛化

B 泛化、關聯、依賴

C 請求、驗證、回應

D 連接配接、聚合、組合

2. 區分泛化和關聯的根本要點是

A 泛化是靜态關系,關聯是動态關系。

B 泛化關注繼承,關聯關注包含。

C 泛化是集合關系,關聯是個體關系。

D 泛化關登出售,關聯關注成本。

3. 以下類關系合理的是:

《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

4. 是否采用"聚合/組合"關聯,考慮的出發點是:

A 對責任配置設定有幫助

B 人類語言表達上"A擁有B"能說得通

C 關聯兩端的多重性

D 類的屬性個數

5. 一台電腦可能是一台台式電腦,也可能不是;一台電腦可能是一台筆記本電腦,也可能不是;一台電腦可能是一台掌上電腦,也可能不是。以下類關系表達正确的是:

 A) 

《軟體方法》第8章 分析 之 分析類圖(3)
 B) 
《軟體方法》第8章 分析 之 分析類圖(3)
 C) 
《軟體方法》第8章 分析 之 分析類圖(3)
 D) 
《軟體方法》第8章 分析 之 分析類圖(3)

6. 以下說法正确的是:

A) 不需要先識别出所有的類,再識别類之間的關系。

B) 如果A變化,B也需要變化,那麼A依賴于B。

C) 自然語言中帶有“A有B”的描述,可以判斷A和B是關聯關系。

D) 從用例規約的各個部分都有可能提煉出分析類。

7. 以下犯了“把泛化當作關聯”錯誤的是:

《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

8. 關于影評網站“逗瓣”,針對以下概念之間的關系描述最合理的是:

A) 

《軟體方法》第8章 分析 之 分析類圖(3)
B) 
《軟體方法》第8章 分析 之 分析類圖(3)
C) 
《軟體方法》第8章 分析 之 分析類圖(3)
D) 
《軟體方法》第8章 分析 之 分析類圖(3)
9. 以下對象圖如果映射回類圖,得到的結果應該是:
《軟體方法》第8章 分析 之 分析類圖(3)
A) 
《軟體方法》第8章 分析 之 分析類圖(3)
B) 
《軟體方法》第8章 分析 之 分析類圖(3)
C) 
《軟體方法》第8章 分析 之 分析類圖(3)
D) 
《軟體方法》第8章 分析 之 分析類圖(3)
10. 泛化關系可以畫成如下圖的樹的形狀,關聯可以嗎?為什麼?
《軟體方法》第8章 分析 之 分析類圖(3)
《軟體方法》第8章 分析 之 分析類圖(3)

繼續閱讀