[英]Java Software Engineering: Composition vs Aggregation
我真的很難理解組合和聚合。 在下面的代碼中,我想知道下面哪個汽車實例使用組合邏輯或聚合邏輯。
public class Engine {
public Engine() {
}
}
public class Car1 {
public final Engine engine;
public Car1() {
engine = new Engine();
}
}
class Car2{
public Engine engine;
public Car2(Engine engine) {
this.engine = engine;
}
}
class Car3{
public final Engine engine;
public Car3(Engine engine) {
this.engine = engine;
}
}
class Car4{
Engine engine;
public Car4(){
this.engine = new Engine();
}
}
class Main{
public static void main(String[] args) {
Engine engine = new Engine();
Car1 car1 = new Car1();
Car2 car2_1 = new Car2(new Engine());
Car2 car2_2 = new Car2(engine);
Car3 car3_1 = new Car3(new Engine());
Car3 car3_2 = new Car3(engine);
Car4 car4_1 = new Car4();
}
}
據我說,car1、car2_1、car3_1 遵循組合邏輯。 但我讀過很多地方 car3_2 也是組合。 為什么? 如果我們銷毀 car3_2 仍然存在引擎實例,那么應該是聚合。
是的,引擎仍然存在於 car3_2 實例之外,所以應該是聚合。
I guess in Java the differences are difficult to see as for any Object you can only store references to some heap location, whereas in other programming languages like C++ you can choose whether one object holds a reference to another object vs one object holds an embedded copy那個 object。
但是我們在 java 中,並查看生命周期....引擎是否會比汽車存在更長時間,這取決於是否有人持有對該引擎的引用。 除 car4 之外的所有汽車都有公開可用的引擎字段,任何人都可以抓住並保留參考,從而在扔掉汽車的同時保留引擎。
我希望 car4 沒有 package (默認),但甚至是私人訪問。 這意味着沒有人應該有權訪問該引擎引用(除非在其他地方泄露)並且您可以談論合成。
編輯:重新閱讀您的問題和代碼示例到底部,我認為問題在於它們是如何構造的。 Car1 和 car4_1 確實帶有自己隱式創建的引擎,並且由於沒有人獲取引用,因此汽車和引擎會同時進行垃圾收集。 我會稱這個組合。
盡管引擎是明確構造的,但 Car2_1 和 car3_1 的行為確實相同。 他們將與各自的引擎一起收集垃圾。 這行為類似,但也允許下一個模式。 我猜它是作為誘餌引入的。
Car2_2 和 car3_2 都共享一個顯式創建的引擎,並且對它的引用存在於 main 方法中。 一輛或兩輛汽車可能會被垃圾收集,但除非放棄所有三個引用,否則引擎將保持不變。 所以這可能應該顯示聚合。
- 聚合意味着子節點可以獨立於父節點而存在的關系。 示例:Class(父)和學生(子)。 刪除 Class 學生仍然存在。
- 組合意味着孩子不能獨立於父母而存在的關系。 示例:房屋(父)和房間(子)。 房間不存在獨立於房屋。
因此,就其本質而言,它不可能是任何 object 的組成:
car3_2
不能是 Composition,因為它與car2_2
共享引擎。
其他都是組成嗎? 從邏輯上講,在Real Life中,您可以將引擎從汽車上卸下並安裝到另一輛汽車上,因此汽車與引擎的關系是聚合。
以編程方式, final
關鍵字防止從Car
中刪除Engine
,但它不會阻止相同的引擎被添加到另一輛車,它不會阻止汽車被“刪除”和引擎改變所有者,所以final
本身並不能確保組合關系。
當構造函數以引擎為參數時, Car
class 無法確保引擎不共享,因此無法確保組合關系。
只有當Engine
由Car
構造函數創建並且該字段是final
的(或有效最終的,本質上是private
的,沒有 setter 方法)時,才能保證遵守 Composition 的定義。
並不意味着以Engine
為參數的其他人不能有效地組合。 這取決於它是如何使用的。 例如,如果Car
是由Factory
class 創建的,則工廠可以強制執行組合規則。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.