区分委托,组合和聚合(Java OOdevise)

我面临着一个持续不断的问题,即将授权,组成和聚合相互区分,并确定最好相互使用的情况。

我已经咨询了Java面向对象的分析和devise书,但是我的困惑依然存在。 主要的解释是这样的:

代表团 :当我的对象使用另一个对象的function,而不改变它。

构图 :我的对象由其他对象组成,这些对象在我的对象被销毁后又不能存在 – 垃圾收集。

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

是否可以举几个简单的例子来展示每个案例,以及背后的理由? 除了我的对象简单地引用另一个对象之外,还可以certificate这些例子怎么样?

提前谢谢了。

在这三种情况下,您的对象都会引用另一个对象。 不同之处在于引用对象的行为和/或生命周期。 一些例子:

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

  2. 聚合:从块build造的玩具屋。 你可以拆卸它,但块会保留。

  3. 代表团:你的老板要你给他喝咖啡,而你却有一个实习生替你做。 授权不是一种types的关联(就像组合/聚合一样)。 后两者已经在Stack Overflow上多次讨论过了

在这个评论中,你会问在每种情况下实现的方式会有什么不同,因为在所有情况下,我们都会调用相关对象的方法。 确实,在每种情况下,我们都会有这样的代码

myRoom.doWork(); myBlock.doWork(); myMinion.doWork(); 

但差异在于相关对象的生命周期和基数。

对于组件,当房屋被创build时,房间就会存在。 所以我们可以在House的构造函数中创build它们。

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

  removeTyre(FrontLeft) addNewTyre(aTyre, BackRight) 

很可能是一个工厂来自一个工厂 – 我们没有用这个工具的任何方法来创build它。

在委派的情况下,甚至可能没有成员variables来保存委托

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

只要实习生取咖啡,对象之间的关系就会持续。 然后它返回到资源池。

代表团

 public class A { private B b = new B(); public void methodA() { b.methodB(); } } 

A客户端, A调用委托B的方法methodB

基本原理。 A类暴露其他地方的行为。 这可能发生在A类inheritance的单inheritance语言中,但是它的客户需要在不同的类中实现的行为。 进一步研究 。

混合委托

 public class A { private B b = new B(); public void methodA() { b.methodB( this ); } } 

涉及简单的转发和代理作为inheritance的替代的代理之间的区别在于被调用者必须接受调用者的参数,例如:

  b.methodB( this ); 

基本原理。 允许类B实例使用类A提供的function,就像类B如果它inheritance自类A但是没有inheritance。 进一步研究 。

组成

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

一旦不再有对类A的特定实例的引用,它的类B实例就被销毁了。

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

聚合

 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 ); } } 

一旦不再有对类A的特定实例的引用,类B实例就不会被销毁。 在这个例子中, AC必须在B被销毁之前被垃圾收集。

基本原理。 允许实例重用对象。 进一步研究 。

没有参考的示范

赋予这些简单模式的名称是由它们的参考关系定义的。

你的书很好解释,让我详细说明一下,并提供一些例子。

代表团:当我的对象使用另一个对象的function,而不改变它。

有时候一个class可能在逻辑上需要很大。 但是大class不是一个好的编码实践。 有时候,一个类的某些function可能以多种方式实现,您可能需要稍微改变一下。

 class FeatureHolder { void feature() { // Big implementation of the feature that you dont want to put in the class Big } } class Big { private FeatureHolder FH = new FeatureHolder(); void feature() { // Delegate to FeatureHolder. FH.feature(); } //.. Other features } 

从上面的例子来看,FH的Big.feature()调用function并没有改变。 这样,Big类就不需要包含特征的实现(分工)。 另外,feature()可以像“NewFeatureHolder”一样被其他类实现,而Big可以select使用新的特性持有者。

构图:我的对象由其他对象组成,这些对象在我的对象被分配后又不能存在 – 垃圾收集。

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

从技术上讲,构成是“一部分”,聚合是指“关系”。 你的arm是你的一部分。 如果你不再活着,你的arm也会死亡。 你的布是不是你的一部分,但你有他们; 你可以做客,你的布料不会跟你一起去。

在编程中,有些对象是另一个对象的一部分,没有它就没有逻辑意义。 例如,一个button组成一个窗口框架。 如果一个框架closures,该button没有理由在(组成)。 一个button可能有一个数据库的引用(如刷新数据); 当button被删除时,数据库可能仍然在(聚合)。

对不起,我的英语,希望这有助于

1)代表团:人驾驶汽车的例子。 一个男人买了一辆车。 但那个男人不知道开车。 所以他会任命一位知道驾驶汽车的司机。 所以曼类想用汽车来进行交通。 但它没有与汽车的交互function/兼容性。 所以他使用了兼容于与人类兼容的驾驶者的汽车类。 假设司机可以理解男人说什么

2)组成:汽车模拟是一个例行的例子。 为了使汽车移动,轮子旋转。 使用车轮类的汽车类将旋转function作为其移动function的一部分,其中车轮是汽车的一部分。

3)聚合:汽车和它的颜色。 汽车类对象ferrari将有一个颜色类对象红色。 但是颜色类对象红色可以作为单独的类,当用户search发生与红色的规格。