《軟件方法》第9章 分析類圖進階(20180619更新)
- 2019 年 10 月 6 日
- 筆記
高坡砍柴要留樁,平地起房要留窗
《野合萬事興》;詞:左小祖咒,曲:左小祖咒,唱:左小祖咒、寶羅,2008
本章在假設讀者已經掌握類建模基本知識的前提下,講述一些可以幫助建模人員得到更高質量類模型的進階建模技能。
9.1 彩色建模
9.1.1 彩色建模思想概述
1999年,Peter Coad、Eric Lefebvre和Jeff De Luca在"Java Modeling In Color With UML"一書中闡述了將顏色用於UML建模的思想。在這本薄薄的、彩色印刷的書中,作者們認為各個領域之間存在一些領域中性(Domain-Neutral)的基本結構,所以使用四種顏色架構型(Archetype)來描述領域內的各種概念,並試圖總結顏色之間的交互規律,為領域建模提供清晰的思路。
正如Peter Coad在書中所說,彩色建模根據他之前歸納的建模模式拓展得來。1992年,Peter Coad就在「Object-Oriented Patterns」一文中闡述了四個架構型,在後來出版的「Object Models: Strategies, Patterns, and Applications」書中也有應用,只是沒有加上顏色。


圖9-1 Peter Coad1992年闡述架構型的文章
本書中講述的彩色建模技能基於Peter Coad等人的工作,加上了自己的一些理解,所以有些地方和原著有區別。
彩色建模的四種顏色架構型分別為事物(PartyPlaceThing)、描述(Description)、角色(Role)和時刻時段(MomentInterval),如圖9-2所示。


圖9-2 四種顏色架構型
如果觀察各個領域,常會觀察到這樣的關係:
(1)「時刻時段」發生了,「事物」們扮演不同的「角色」參與進來。
(2)「事物」變化的規律和「描述」有關。
例如,當前您在做的「閱讀」事件就是一個時刻時段,發生在某個時間,而「閱讀」需要「閱讀者」和「讀物」兩個角色參與,這兩個角色分別由「軟件開發人員」和「軟件開發書籍」這兩個「事物」扮演。「軟件開發人員」讀什麼樣的「軟件開發書籍」,很可能是由「軟件開發人員類型」和「軟件開發書籍類型」之間的關係決定的。如圖9-3所示。

圖9-3 四種架構型的關係
首先要說的是,顏色架構型只是一些建模的提示和建議。不是所有的領域都會有圖9-3的關係,如果您所關注的領域沒有找到圖9-3的關係,也不必生搬硬套,有些類不知道怎麼塗顏色就不塗也無所謂;另外,關係也不一定非得像圖9-3,也有可能是「時刻時段-描述」、「事物-事物」等。
9.1.2 事物(PartyPlaceThing)
「事物」在這裡的含義並非「看得見摸得着的東西」,而是「狀態最豐富的東西」。萬事萬物只要我們樂意,都可以找出它的狀態變化,但是一個特定的系統往往是圍繞一個或幾個關鍵概念的狀態變化而展開的。
圖9-4是某個設備管理系統的部分類圖。

圖9-4 某個設備管理系統的部分類圖
可以判斷,該系統是圍繞着「設備」的狀態變化而展開的,那麼,可以把「設備」塗成綠色。如圖9-5所示。

圖9-5 給「設備」塗上顏色
很容易畫出「設備」的狀態機圖,如圖9-6所示。

圖9-6 「設備」的狀態機圖
從以上可以看出「事物」架構型的特點:
(1)它的狀態非常值得關注。
(2)在其身上發生領域事件。
9.1.3 描述(Description)
「事物」的許多特徵並不由「事物」本身決定,而是由背後的「描述」決定。
以圖9-5中的類為例,單位採購了10台品牌型號完全相同的設備,每一台設備都要編號區分,而且「可借」、「故障」等狀態也各自不同,但是,設備的品牌型號以及各種參數是一樣的。這些內容應該分離到「設備規格」類中。這個「設備規格」就可以看作「描述」,塗色如圖9-7。

圖9-7 給「設備規格」塗上顏色
「事物」和「描述」的分離,大大減少了冗餘的信息。對於結構複雜多變的「事物」,可以在「描述」級別定義好規則,「事物」級別按照規則執行即可。常見類圖如圖9-8所示。

圖9-8 「事物」和「描述」的分離
例如,應用在「公文」上,可以得到圖9-9。

圖9-9 公文和公文模板的分離
從以上可以看出「描述」架構型的特點:
(1)對象個數較少。
(2)封裝某方面的規則。
(3)狀態變化不值得關注。
9.1.4 時刻時段(MomentInterval)
「時刻時段」是帶有時間屬性的類,相當於「事件」類。
這些類就像錄像機一樣,把圍繞着「事物」發生的各種事件錄下來。既然是錄像機,錄下來的信息是不好修改的,要麼留着,要麼刪掉。
我們給上面的設備管理系統類圖中的「時刻時段」類塗上顏色,得到圖9-10。

圖9-10 給「時刻時段」架構型塗上顏色
從圖9-10可以看到,我們給每個粉紅色的類都加上了時間屬性。「設備的時間」或「設備規格的時間」說不通,但「租借的時間」就說得通了。
從以上可以看出「時刻時段」架構型的特點:
(1)對象個數多。
(2)屬性值不應該被修改。
9.1.5 角色(Role)
「角色」放在「事物」和「時刻時段」之間,起到解耦的作用。「角色」的表示可以是顯式的,也可以是隱式的。
我們給上面的設備管理系統類圖加上「角色」,得到圖9-11。

圖9-11 給設備管理系統類圖加上「角色」
像圖9-11這樣顯式表示「角色」太佔地方了,如果不需要為「角色」類分配責任,可以把它縮到關聯的角色中,如圖9-12所示。

圖9-12 隱式表示「角色」
9.1.6 顏色的作用
給類標上顏色後,我們就可以使用一些常見的套路來幫助建模,包括類圖建模和序列圖建模的套路。
套路1:從「時刻時段」開始建模,逐步找出後面的「角色」和「事物」,如圖9-13所示。

圖9-13 從「時刻時段」開始推導
「時刻時段」是最容易觀察到的,從「時刻時段」開始推導,比較符合人的思考習慣。將這個套路應用到上面的設備管理系統例子,如圖9-14所示。

圖9-14 從「時刻時段」開始推導設備管理系統的類
套路2:從「描述」之間的關係開始建模,然後在其上添加「事物」,如圖9-15所示。

圖9-15 從「描述」開始推導
「描述」之間的關係很可能描述了系統關注的領域規則。只要把規則描述清楚了,剩下的無非是在規則上玩遊戲而已。將這個套路應用到上面的設備管理系統例子,如圖9-16所示。

圖9-16 從「描述」開始推導設備管理系統的類
在責任分配上,也會有如圖9-17的套路。


圖9-17 架構型之間的責任分配
將這個套路應用到上面的設備管理系統例子,如圖9-18所示。


圖9-18 架構型之間的責任分配應用到設備管理系統
在使用顏色來標記類時,要謹記同樣一個類在不同上下文中顏色可以不同。還是以上面的設備管理系統為例,如果設備的租借需要收押金並按租借時長收費,費用的支付情況是系統非常關心的,那麼可以把「租借」塗成綠色,「租借」上發生的事件則變成了粉紅色,時間屬性移到粉紅色的類上。類圖和「租借」的狀態機圖如圖9-19所示。


圖9-19 「租借」變得重要時的顏色和狀態機圖
9.2 常見分析模式
9.2.1 模式
長期以來在軟件開發人員中存在一個誤解:模式=設計模式=GoF23模式。我提供服務的這些年,經常碰到這樣的情況:
客戶:潘老師,來給我們講講設計模式吧!
我:我猜你說的設計模式就是那23個模式吧,設計可以講,模式也可以講,這些都有用,光講那23個沒用的。
客戶(愕然):啊?設計不就是學那23個設計模式嗎,不是說學會了23個設計模式就掌握設計了嗎?
其實GoF23模式不是最有用的,也不是最本質的,只不過這些模式比較早(也並非最早)寫在書上,碰巧這本書在所有模式出版物中最出名。我們可以用中國象棋做類比。《橘中秘》是名氣最大、翻印版本最多的古代象棋書籍,裏面歸納了很多象棋的「模式」,但該書不是最早的,裏面的知識也不是最有用和最本質的。很難想像現代人學習中國象棋會直接拿起《橘中秘》來學習。



圖 9-20 GoF設計模式和《橘中秘》
模式的世界遠遠比GoF要大,不同的工作流、不同的平台都有人歸納了不同的模式,如圖9-21所示。






圖9-21 各種各樣的模式
Hillside Group主辦的PLoP(Pattern Languages of Programs,程序設計的模式語言)、EuroPLoP會議每年都舉辦,是軟件模式領域最重要的會議。POSA系列和PLoPD系列模式書籍都已經各自出到了第5集。如圖9-22所示。




圖9-22 模式會議和POSA、PLoPD系列模式書籍
開發人員應該重點學習自己當前項目所處核心域的分析模式以及所用實現平台相關的設計模式,而不是死盯着GoF模式。例如,如果在.net平台下做一個預訂機票的系統,那麼應該重點搜索「機票預訂的分析模式」以及「.net平台的架構模式」相關資料來學習。
9.2.2 常用變化:泛化和關聯的轉換
如果改變抽象的級別,泛化關係可以用更抽象的類之間的關聯關係代替。例如我們可以說「人分為男人和女人兩種」,也可以說「人有性別」,如圖9-23所示。

圖9-23 泛化關係可以用更抽象的類之間的關聯關係代替
如果重點是數據的表達,例如統計人口,那麼圖9-23右側的關聯就夠了,「人」有一個屬性「性別」,不需要泛化關係;如果重點是行為的變異,例如遊戲中男人和女人行為區別很大,應該考慮使用泛化關係。
很多模式通過把泛化轉成關聯來簡化模型,套路如圖9-24。


圖9-24泛化轉成關聯的套路
下面我們來看一些常見的分析模式。
9.2.3 人員
人員的管理是很多系統不得不考慮的。假設要記錄圖9-25中人員資料,直接的做法就是照貓畫虎得到圖9-26。

圖9-25 需要記錄的人員資料

圖9-26 照貓畫虎的人員類圖
從數據庫設計的角度也可以看出圖9-26中「電話1」、「電話2」等違反了第一範式,如果有更多的「電話」需要記錄怎麼辦呢?可以考慮把這些多重性大於1的屬性分離出來,如圖9-27所示。

圖9-27 分離多重性大於1的屬性
圖9-27有一些改進,但還是很難應對變化,其他屬性如QQ、微信可不可以多個呢?完全有可能。而且,隨着時代的不斷進步,人的屬性不斷進化,許多以前關注的屬性現在已經不再關注,例如傳真、MSN等等,但是多了很多新的屬性,例如微信、微博。如果採用圖9-27的結構,就需要刪除或增加「人員」的屬性或關聯線。
一種改進方法是添加泛化關係來隔離「人員」和具體聯繫方式屬性,如圖9-28所示。

圖9-28 通過泛化隔離變化
從圖9-24的套路可知,這樣的結構可以變化成圖9-29。

圖9-29 泛化轉成關聯
如果覺得圖9-29不好理解,可以把類模型轉成關係數據庫模型,填上數據幫助理解。圖9-30展示了映射到關係數據庫之後,將圖9-25所示人員的信息填充到「聯繫方式」表時的數據。

圖9-30 關係數據庫里的數據表示
進一步抽象之後,一些概念也可以理得更清楚。例如,人員之所以有若干個電話、手機、微信……,原因可能是用途不同。如果直接映射到模型,就會得到「辦公電話」、「住宅電話」、「辦公手機」、「私人手機」等屬性。做了圖9-29的抽象之後,直接在「聯繫方式」上關聯一個類「用途」即可,如圖9-31所示。

圖9-31 指明聯繫方式的用途
有些聯繫方式類型之間允許綁定。例如,電子郵件地址可綁定QQ帳號、MSN賬號;從QQ號可以推導QQ郵箱地址和微信;從手機號可以推導139郵箱和微信,等等。注意,上面說的「可以」指的是聯繫方式類型的規則,具體聯繫方式是否綁定是不一定的。圖9-32通過添加自反關聯,表達了「可以綁定」和「綁定」的知識。

圖9-32 指明聯繫方式的綁定關係
聯繫方式還有驗證合法性的問題。通過以上抽象,這個問題也簡單了。驗證合法性的規則和具體的聯繫方式無關,只和聯繫方式類型相關。假設用正則表達式驗證,可以有:
電子郵件:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
電話:d{3}-d{8}|d{4}-d{7}
手機:^[1][3,4,5,7,8][0-9]{9}$
把正則表達式作為「聯繫方式類型」的屬性,可以大大簡化用於表達行為的代碼。
人員之間存在各種關係。圖9-33是一張網絡上流傳甚廣的人際關係圖。

圖9-33 娛樂圈的複雜人際關係
圖9-33相當於一張UML對象圖,類其實只有一個:人員。人員之間存在的各種人際關係可以用自反關聯表達,如圖9-34。

圖9-34 用自反關聯表達人際關係
當人際關係類型較多時,「人員」類周圍就會圍上很多個自反關聯的圈圈,可以引入「人際關係類型」,把這些圈圈合併成一個,圈圈之間的區別在「人際關係類型」中描述。如圖9-35。

圖9-35 抽象出人際關係類型
如果覺得圖9-35不好理解,可以把類模型轉成關係數據庫模型,填上數據幫助理解。圖9-36展示了映射到關係數據庫並填充數據後的情況。



圖9-36 關係數據庫數據示例
抽象出「人際關係類型」後,就可以反映人際關係中的一些約束,例如:如果兩人性別相同,那麼這兩人之間不該出現夫妻關係。類圖如圖9-37。

圖9-37 人際關係中的約束
