关于构成与聚合的混淆(重新制定和纠正)

时间:2015-08-19 19:35:44

标签: java php oop

这是我之前问过的一个改写的问题,但是没有很好地表达并包含一些错误(包括我提到的答案,抱歉)所以我再试一次,希望这个问题更有意义。

我对以下主题中的一个答案感到困惑,我在第三个答案中指的是代码片段(目前有117个upvotes):
Prefer composition over inheritance?

答案说明了使用依赖注入的组合,请参阅代码片段)。

编辑:在下面重复:

class Person {
   String Title;
   String Name;
   Int Age;

   public Person(String title, String name, String age) {
      this.Title = title;
      this.Name = name;
      this.Age = age;
   }

}

class Employee {
   Int Salary;
   private Person person;

   public Employee(Person p, Int salary) {
       this.person = p;
       this.Salary = salary;
   }
}

Person johnny = new Person ("Mr.", "John", 25);
Employee john = new Employee (johnny, 50000);

令我困惑的是,在学校,我们了解到:
- 直接关联(与此问题无关);
- 聚合:弱关系 - >具有-A-关系;
- 成分:强烈的关系 - >所有权,一个人不能没有另一个。

学校给出的例子暗示DI是聚合的一部分,因为它表明关系薄弱 与组合相反,其中示例表明ClassB在classA的构造函数中实例化,或者由classA的setter实例化。 ClassA明确地负责创建classB(否则classB不存在) 给出的示例是Person类,其中Heart类在Person类的构造函数中实例化。

假设是否正确依赖注入意味着聚合,或者也可能有一个具有组合的DI?

1 个答案:

答案 0 :(得分:0)

理解组合关系的关键是所包含的对象是已知的,并且除了容器对象之外什么都不用。在人类包含哈特的例子中,与人类的交互从不涉及直接操纵哈特。因此,它是一种遏制关系。如果心脏暴露给他人操纵,那么这将是一种聚合关系。

现在只是因为构造Employee的对象必须构造包含的Person并不能阻止该关系成为包含之一。您的示例中的关键是person字段是私有的,并且员工对象之外没有办法操纵其人员。这就是遏制而不是聚合的原因。

我承认你可以设置一个讨厌的案例,其中构造john的对象持有johnny并继续操纵它。实际上,此对象将在不调用其任何方法的情况下更改john的状态。这是非常糟糕的做法,不要这样做。

- 继续 -

并且更倾向于遏制继承"理念。我建议你也喜欢遏制聚合。包含关系意味着应用程序的重要部分可以忽略所包含的类甚至存在于系统中的事实。这是因为他们所有的交互都是与容器而不是包含的。

当然,有时候遏制是不可能的,而且在表达相关关系时,聚合在逻辑上是必要的。