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 实例之外,因此应该是聚合。

我想在 Java 中很难看出差异,因为对于任何对象,您只能存储对某个堆位置的引用,而在其他编程语言(如 C++)中,您可以选择一个对象是否包含对另一个对象 vs 一个对象拥有该对象的嵌入副本。

但我们处于 java,并且正在查看生命周期.... 引擎是否会比汽车存在的时间更长取决于是否有人持有该引擎的引用。除了 car4 之外的所有汽车都有一个公开可用的引擎字段,任何人都可以抓住并保留参考,从而在扔掉汽车的同时保留引擎。

我更希望 car4 没有包(默认),但即使是私人访问。这意味着没有人应该有权访问该引擎引用(除非它被泄露到其他地方)并且你可以谈论组合。

编辑:重新阅读您的问题和代码示例到底层,我认为问题在于它们的构造方式。 Car1 和 car4_1 确实带有它们自己隐式创建的引擎,并且由于没有人获取引用,汽车和引擎会同时收集垃圾。我会称这个作文。

Car2_1 和 car3_1 确实表现相同,尽管引擎是明确构建的。他们将与各自的引擎一起收集垃圾。这表现类似,但也允许下一个模式。我猜它是作为诱饵引入的。

Car2_2 和 car3_2 都共享一个显式创建的引擎,并且对它的引用存在于 main 方法中。一辆或两辆汽车都可以收集垃圾,但除非放弃所有三个参考,否则发动机将保留。所以这可能应该显示聚合。

  • Aggregation implies a relationship where the child can exist independently of the parent. Example: Class (parent) and Student (child). Delete the Class and the Students still exist.
  • Composition implies a relationship where the child cannot exist independent of the parent. Example: House (parent) and Room (child). Rooms don't exist separate to a House.

因此,就其本质而言,它不能是任何对象的组合

  • 可以拥有多个其他对象
  • 可以无主(初始化完成后)
  • 可以更改所有者

car3_2 不能是 Composition,因为它与 car2_2.

共享引擎

其他都是Composition吗?按理来说,在Real Life中,你可以把一辆车的引擎拆下来装在另一辆车上,所以车-引擎的关系是Aggregation。

在编程上,final 关键字可防止从 Car 中删除 Engine,但它不会阻止将同一引擎添加到另一辆车,而且它不会t 阻止汽车 "deleted" 和引擎改变所有者,因此 final 本身并不能确保组合关系。

当构造函数以引擎为参数时,Carclass不能保证引擎不共享,所以不保证Composition关系

仅当 EngineCar 构造函数创建且字段为 final(或有效最终,本质上是 private 而没有 setter 方法),是否保证 Composition 的定义得到尊重。

并不意味着其他以Engine为参数的不能有效组合。这取决于它的使用方式。例如。如果 Car 是由 Factory class 创建的,工厂可以强制执行组合规则。