区分委托,组合和聚合(Java OOdevise)
我面临着一个持续不断的问题,即将授权,组成和聚合相互区分,并确定最好相互使用的情况。
我已经咨询了Java面向对象的分析和devise书,但是我的困惑依然存在。 主要的解释是这样的:
代表团 :当我的对象使用另一个对象的function,而不改变它。
构图 :我的对象由其他对象组成,这些对象在我的对象被销毁后又不能存在 – 垃圾收集。
聚合 :我的对象由其他对象组成,即使在我的对象被销毁后也可以存在。
是否可以举几个简单的例子来展示每个案例,以及背后的理由? 除了我的对象简单地引用另一个对象之外,还可以certificate这些例子怎么样?
提前谢谢了。
在这三种情况下,您的对象都会引用另一个对象。 不同之处在于引用对象的行为和/或生命周期。 一些例子:
-
组成:房子包含一个或多个房间。 房间的一生是由房子控制的,因为没有房子的房间就不存在了。
-
聚合:从块build造的玩具屋。 你可以拆卸它,但块会保留。
-
代表团:你的老板要你给他喝咖啡,而你却有一个实习生替你做。 授权不是一种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
实例就不会被销毁。 在这个例子中, A
和C
必须在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发生与红色的规格。