談一談自己對依賴、關聯、聚合和組合之間區別的理解
在學習物件導向設計物件關係時,依賴、關聯、聚合和組合這四種關係之間區別比較容易混淆。特別是後三種,僅僅是在語義上有所區別,所謂語義就是指上下文環境、特定情景等。他們在程式語言中的體現卻是基本相同的,但是基本相同並不等於完全相同,這一點在我的前一篇博文《設計模式中類的關係》中已經有所提及,下面就來詳細的論述一下在java中如何準確的體現依賴、關聯、聚合和組合。
首先看一看書上對這四種關係的定義:
- 依賴(Dependency)關係是類與類之間的聯接。依賴關係表示一個類依賴於另一個類的定義。例如,一個人(Person)可以買車(car)和房子(House),Person類依賴於Car類和House類的定義,因為Person類引用了Car和House。與關聯不同的是,Person類裡並沒有Car和House型別的屬性,Car和House的例項是以參量的方式傳入到buy()方法中去的。一般而言,依賴關係在Java語言中體現為局域變數、方法的形參,或者對靜態方法的呼叫。
- 關聯(Association)關係是類與類之間的聯接,它使一個類知道另一個類的屬性和方法。關聯可以是雙向的,也可以是單向的。在Java語言中,關聯關係一般使用成員變數來實現。
- 聚合(Aggregation) 關係是關聯關係的一種,是強的關聯關係。聚合是整體和個體之間的關係。例如,汽車類與引擎類、輪胎類,以及其它的零件類之間的關係便整體和個體的關係。與關聯關係一樣,聚合關係也是通過例項變數實現的。但是關聯關係所涉及的兩個類是處在同一層次上的,而在聚合關係中,兩個類是處在不平等層次上的,一個代表整體,另一個代表部分。
- 組合(Composition) 關係是關聯關係的一種,是比聚合關係強的關係。它要求普通的聚合關係中代表整體的物件負責代表部分物件的生命週期,組合關係是不能共享的。代表整體的物件需要負責保持部分物件和存活,在一些情況下將負責代表部分的物件湮滅掉。代表整體的物件可以將代表部分的物件傳遞給另一個物件,由後者負責此物件的生命週期。換言之,代表部分的物件在每一個時刻只能與一個物件發生組合關係,由後者排他地負責生命週期。部分和整體的生命週期一樣。
——摘自《Java物件導向程式設計》,作者:孫衛琴
以上關係的耦合度依次增強(關於耦合度的概念將在以後具體討論,這裡可以暫時理解為當一個類發生變更時,對其他類造成的影響程度,影響越小則耦合度越弱,影響越大耦合度越強)。由定義我們已經知道,依賴關係實際上是一種比較弱的關聯,聚合是一種比較強的關聯,而組合則是一種更強的關聯,所以籠統的來區分的話,實際上這四種關係、都是關聯關係。
依賴關係比較好區分,它是耦合度最弱的一種,在java中表現為局域變數、方法的形參,或者對靜態方法的呼叫,如下面的例子:Driver類依賴於Car類,Driver的三個方法分別演示了依賴關係的三種不同形式。
class Car { public static void run(){ System.out.println("汽車在奔跑"); } } class Driver { //使用形參方式發生依賴關係 public void drive1(Car car){ car.run(); } //使用區域性變數發生依賴關係 public void drive2(){ Car car = new Car(); car.run(); } //使用靜態變數發生依賴關係 public void drive3(){ Car.run(); } }
關聯關係在java中一般使用成員變數來實現,有時也用方法形參的形式實現。依然使用Driver和Car的例子,使用方法引數形式可以表示依賴關係,也可以表示關聯關係,畢竟我們無法在程式中太準確的表達語義。在本例中,使用成員變數表達這個意思:車是我自己的車,我“擁有”這個車。使用方法參數列達:車不是我的,我只是個司機,別人給我什麼車我就開什麼車,我使用這個車。
class Driver { //使用成員變數形式實現關聯 Car mycar; public void drive(){ mycar.run(); } ... //使用方法引數形式實現關聯 public void drive(Car car){ car.run(); } }
聚合關係是是一種比較強的關聯關係,java中一般使用成員變數形式實現。物件之間存在著整體與部分的關係。例如上例中
class Driver { //使用成員變數形式實現聚合關係 Car mycar; public void drive(){ mycar.run(); } }
假如給上面程式碼賦予如下語義:車是一輛私家車,是司機財產的一部分。則相同的程式碼即表示聚合關係了。聚合關係一般使用setter方法給成員變數賦值。
假如賦予如下語義:車是司機的必須有的財產,要想成為一個司機必須要先有輛車,車要是沒了,司機也不想活了。而且司機要是不幹司機了,這個車就砸了,別人誰也別想用。那就表示組合關係了。一般來說,為了表示組合關係,常常會使用構造方法來達到初始化的目的,例如上例中,加上一個以Car為引數的構造方法
public Driver(Car car){ mycar = car; }
所以,關聯、聚合、組合只能配合語義,結合上下文才能夠判斷出來,而只給出一段程式碼讓我們判斷是關聯,聚合,還是組合關係,則是無法判斷的。
相關文章
- java的類之間的關係:泛化、依賴、關聯、實現、聚合、組合Java
- 組合,關聯,聚合的區別
- UML關係(泛化,實現,依賴,關聯(聚合,組合))
- 學習UML實現、泛化、依賴、關聯、聚合、組合
- JAVA面試題之UML泛化、實現、依賴、關聯、組合、聚合書目錄Java面試題
- 關聯關係與依賴關係的區別
- 用C++程式碼描繪UML中的 關聯 依賴 組合 聚合 泛化C++
- 淺談querySelector和getElementById之間的區別
- [轉載]繼承(Generalization),組合(Composition),聚合(Aggregation),關聯(Association),依賴(Dependency),實現(Realization繼承
- 談談機器學習與傳統程式設計之間的區別機器學習程式設計
- 談談對MVC、MVP和MVVM的理解?MVCMVPMVVM
- 簡單談談Hilt——依賴注入框架依賴注入框架
- 談談import和require的區別ImportUI
- 談談mysql和redis的區別MySqlRedis
- 談一談對vuex的簡單理解Vue
- 淺談迴圈依賴
- 淺談DNS遞迴解析和迭代解析之間的區別DNS遞迴
- 結合自己的經驗談一談關於專案管理的一點感想薦專案管理
- 每日一問:談談對 MeasureSpec 的理解
- 談一談我對Spring Resource的理解Spring
- 談談持續整合,持續交付,持續部署之間的區別
- 區間統計 聚合函式組合器函式
- 談談你對Promise的理解Promise
- 談談對中斷的理解
- 談談對BPM的理解(轉)
- 談談依賴注入與面向介面程式設計依賴注入程式設計
- 談一談對vue-router的簡單理解Vue
- Oracle 查詢鎖之間的依賴關係Oracle
- 【轉】理解 CI 和 CD 之間的區別
- 談談對Spring IOC的理解Spring
- 談談我對Monad的理解
- 物件導向程式設計程式碼詳解(依賴關係,關聯關係,組合關係)物件程式設計
- 談一談Coders Programmer Developer的區別Developer
- UML-類圖-Composition(組合)和Aggregation(聚合)的區別
- JAVA面試題 請談談你對Sychronized關鍵字的理解?Java面試題Zed
- 談談我對深拷貝和淺拷貝的理解
- 設計模式漫談之組合模式設計模式
- 從Immutable來談談對於執行緒安全的理解誤區執行緒