簡體   English   中英

Java 軟件工程:組合與聚合

[英]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 的組成:

  • 可以多個其他 object 擁有
  • 可以是無主的(初始化完成后)
  • 可以更改所有者

car3_2不能是 Composition,因為它與car2_2共享引擎。

其他都是組成嗎? 從邏輯上講,在Real Life中,您可以將引擎從汽車上卸下並安裝到另一輛汽車上,因此汽車與引擎的關系是聚合。

以編程方式, final關鍵字防止從Car中刪除Engine ,但它不會阻止相同的引擎被添加到另一輛車,它不會阻止汽車被“刪除”和引擎改變所有者,所以final本身並不能確保組合關系。

當構造函數以引擎為參數時, Car class 無法確保引擎不共享,因此無法確保組合關系。

只有當EngineCar構造函數創建並且該字段是final的(或有效最終的,本質上是private的,沒有 setter 方法)時,才能保證遵守 Composition 的定義。

並不意味着以Engine為參數的其他人不能有效地組合。 這取決於它是如何使用的。 例如,如果Car是由Factory class 創建的,則工廠可以強制執行組合規則。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM