淺談UML中類之間的五種關系及其在代碼中的表現形式


什么是類?

將某類東西歸納在一起,可以成為一個類。

類有很多種提煉角度,需要根據系統地目標、業務的場景,選取合適的角度對事物進行歸納。

什么是類圖?

類圖可能是UML中使用的最多的一種圖。

和其他圖一樣,類圖的基本語法並不復雜,可能一兩天就能掌握,但是真正做到靈活的使用類圖,可能需呀多年的功力。

類圖是鍛煉OOA(OO Analysis)和OOD(OO Design)思想的重要工具,有助於OOA、OOD思想的提升。

本篇博文,重點講述類圖中類與類之間的關系以及這種關系在代碼中的實現形式。寫作本文的原因是:網上關於UML類圖的語法規則等的資料很多,但是涉及到關系在代碼中實現形式的文章卻很少。這是很容易理解的:UML語法規范什么的各種書上導出都是,網頁上的也很多都是對各種語法規范的Copy;而類之間的關系反應到代碼層面需要加入個人的理解。兩者的區別是一個不需要動腦子,Copy過來就行,而另一個需要動腦子。

類與類之間的關系

類與類之間的關系可以根據關系的強度依次分為以下五種:

依賴關系(Dependency)---關聯關系(Association)---聚合(Aggregation)---組合(Composition)---泛化(Generalization)

1.依賴關系(Dependency)

依賴關系使用虛線加箭頭表示,如下圖所示:

 

 這個例子可能不太好(Animal體內有Water,),換一個:

解釋以下:Person 和 Computer之間是沒有關系的,但是由於偶爾的需要,Person需要使用Computer,這時Person就依賴於Computer.

依賴關系是五種關系中耦合最小的一種關系。

類A要完成某個功能必須引用類B,則類A依賴類B。C#不建議雙向依賴,也就是相互引用。

上述依賴關系在代碼中的表現形式:這兩個關系類都不會增加屬性。

那么,Person類如何使用Computer類呢?有三種方式:

依賴關系的三種表現形式:

1.Computer類是public的,Person類可以調用它。

2.Computer類是Person類中某個方法的局部變量,則Person類可以調用它。代碼如下:

Person有一個Programing方法,Computer類作為該方法的變量來使用。

注意Computer類的生命周期,當Programing方法被調用的時候,才被實例化。

持有Computer類的是Person類的一個方法,而不是Person類,這點是最重要的。

3.Computer類作為Person類中某個方法的參數或返回值。

Computer類被Person類的一個方法所持有,生命周期隨着方法執行結束而結束。

在依賴關系中,必須使用這三種方法之一。

2.關聯關系(Association)

 關聯關系是實線加箭頭表示。表示類之間的關系比依賴要強。

例如,水和氣候是關聯的,表示如下:

在代碼中的表現如下:

可見,在Water類屬性中增加了Climate類。

關聯關系有單向關聯、雙向關聯、自身關聯、多維關聯等等。其中后三個可以不加箭頭。

單向關聯:

雙向關聯:

自身關聯:

多維關聯:

關聯和依賴的區別:

  • 從類的屬性是否增加的角度看:

發生依賴關系的兩個類都不會增加屬性。其中的一個類作為另一個類的方法的參數或者返回值,或者是某個方法的變量而已。

發生關聯關系的兩個類,其中的一個類成為另一個類的屬性,而屬性是一種更為緊密的耦合,更為長久的持有關系。

  • 從關系的生命周期來看:

依賴關系是僅當類的方法被調用時而產生,伴隨着方法的結束而結束了。

關聯關系是當類實例化的時候即產生,當類銷毀的時候,關系結束。相比依賴講,關聯關系的生存期更長。

 3.聚合(Aggregation)

 4.組合(Composition)

引用程傑的《大話設計模式》里舉大那個大雁的例子 :

大雁喜歡熱鬧害怕孤獨,所以它們一直過着群居的生活,這樣就有了雁群,每一只大雁都有自己的雁群,每個雁群都有好多大雁,大雁與雁群的這種關系就可以稱之為聚合

另外每只大雁都有兩只翅膀,大雁與雁翅的關系就叫做組合

有此可見:

聚合的關系明顯沒有組合緊密,大雁不會因為它們的群主將雁群解散而無法生存;

而雁翅就無法脫離大雁而單獨生存——組合關系的類具有相同的生命周期。

聚合關系圖:

組合關系圖:

 在代碼中表現如下:

 這兩種關系的區別是:

1.構造函數不同

  • 聚合類的構造函數中包含另一個類的實例作為參數

因為構造函數中傳遞另一個類的實例,因此大雁類可以脫離雁群類獨立存在。

  • 組合類的構造函數包含另一個類的實例化

因為在構造函數中進行實例化,因此兩者緊密耦合在一起,同生同滅,翅膀類不能脫離大雁類存在。

2.信息的封裝性不同

在聚合關系中,客戶端可以同時了解GooseGroup類和Goose類,因為他們是獨立的。

在組合關系中,客戶端只認識大雁類,根本不知道翅膀類的存在,因為翅膀類被嚴密地封裝在大雁類中。

5.泛化(Generalization)

泛化是學術名稱,通俗的來講,通常包含類與類之間的繼承關系和類與接口實現關系。

類與類之間的泛化

接口的實現

 題外話:這種東西不可紙上談兵,需要多多實踐,實踐-認識-再實踐-再認識,不斷地批評與自我批評。


理解這個就能看懂各種:設計模式(的UML描述),並且構建相應的C#代碼!

歡迎批評指正,Wish it helps.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM