区分委派、组合和聚合(Java OO 设计)代表团组成集合体无参考演示

2022-08-31 15:48:18

我面临着一个持续存在的问题,即如何区分委派、组成和聚合,并确定最好使用一种而不是另一种的情况。

我查阅了一本Java OO分析和设计书,但我的困惑仍然存在。主要解释是这样的:

委派:当我的对象按原样使用另一个对象的功能而不更改它时。

组合:我的对象由其他对象组成,这些对象在我的对象被销毁后无法存在 - 垃圾回收。

聚合:我的对象由其他对象组成,即使我的对象被销毁,这些对象也可以存活。

有没有可能有几个简单的例子来演示每个案例,以及它们背后的推理?除了我的对象只是对另一个对象的引用之外,如何才能证明这些示例?


答案 1

代表团

public class A {
  private B b = new B();

  public void methodA() {
    b.methodB();
  }
}

当调用的客户端时,类将调用委托给 的 。AmethodAABmethodB

理由。A 类暴露属于其他位置的行为。这可能发生在单继承语言中,其中类A从一个类继承,但其客户端需要在另一个类中实现的行为。进一步研究

混合委派

public class A {
  private B b = new B();

  public void methodA() {
    b.methodB( this );
  }
}

涉及简单转接的委派和作为继承替代的委派之间的区别在于,被叫方必须接受调用方的参数,例如:

    b.methodB( this );

理由。允许类实例使用类中可用的功能,就像类从类继承一样 --但没有继承。进一步研究BABA

组成

public class A {
  private B b = new B();

  public A() {
  }
}

一旦不存在对类的特定实例的引用,其类的实例就会被销毁。AB

理由。允许类以模块化方式定义行为和属性。进一步研究

集合体

public class A {
  private B b;

  public A( B b ) {
    this.b = b;
  }
}

public class C {
  private B b = new B();

  public C() {
    A a = new A( this.b );
  }
}

一旦没有更多对类的特定实例的引用,它的类实例就不会被销毁。在此示例中,两者都必须在垃圾回收之前被销毁。ABACB

理由。允许实例重用对象。进一步研究

无参考演示

为这些简单模式指定的名称由其引用关系定义。


答案 2

在所有三种情况下,您的对象都将引用另一个对象。区别在于引用对象的行为和/或生命周期。一些例子:

  1. 组成:房屋包含一个或多个房间。房间的寿命由房子控制,因为没有房子房间就不会存在。

  2. 聚合:由方块建造的玩具屋。您可以拆卸它,但块将保留。

  3. 代表团:你的老板让你给他喝杯咖啡,你有一个实习生为你做。委派不是一种关联类型(如组合/聚合)。后两者已经在Stack Overflow上讨论过很多次

在注释中,您询问每种情况下的实现有何不同,并观察到在所有情况下,我们都在相关对象上调用方法。确实,在每种情况下,我们都会有这样的代码:

myRoom.doWork();

myBlock.doWork();

myMinion.doWork();

但不同之处在于相关对象的生命周期和基数。

对于组件,房间在创建房屋时就存在。因此,我们可以在房屋的构造器中创建它们。

在协会的情况下(我将使用轮胎和汽车),汽车可能会在其构造器中添加轮胎,但稍后您可能需要移除和更换轮胎。所以你也有这样的方法

 removeTyre(FrontLeft)
 addNewTyre(aTyre, BackRight)

而且aTyre对象很可能来自工厂 - 我们没有在任何汽车的方法中使用它。new

在委派的情况下,您甚至可能没有成员变量来保存委派

 resourcingPool().getIntern().getCoffee(SkinnyLatte, workstation 7);

只要实习生在拿咖啡,物体之间的关系就会持续下去。然后返回到资源池。