看到关于构图/聚合/关联的所有答案是很奇怪的。 谁/这些概念的来源是什么?
最后是我可爱的stackoverflow(至少我很高兴答案未标记为已验证)
What is the difference between association, aggregation and composition?
What is the difference between aggregation, composition and dependency?
有一本很棒的书“ 设计模式” GoF
它描述了在面向对象的系统中重用功能的两种最常用的技术: 1)类继承(is-a) 2)对象组成(has-a)
“对象组合是类继承的一种替代方法。这里,通过组合或组合对象以获得更复杂的功能来获得新的功能。”
与“关联”不同,“组成”是一个非常具有描述性的术语,用于表达对象之间的关系。 为什么上述所有这些来源都以错误的方式使用了“合成”一词?!
走得更远。
对象可以通过两种方式组成:
1)聚合
2)相识
“考虑对象聚合和相识之间的区别,以及它们在编译时和运行时表现出不同的方式。聚合意味着一个对象拥有另一个对象或对该对象负责。通常,我们说一个对象具有或属于其中一部分另一个对象。聚集表示聚集对象及其所有者具有相同的生存期。”
汇总对象及其所有者具有相同的生存期 !!!!
“相识意味着一个对象仅知道另一个对象。有时相识称为“关联”或“使用”关系。相识的对象可以请求彼此进行操作,但彼此不负责。比聚合的关系弱,并且建议对象之间的耦合要宽松得多。”
“容易混淆聚合和熟人,因为它们通常以相同的方式实现。在Smalltalk中,所有变量都是对其他对象的引用。在编程语言中,聚合和熟人之间没有区别。在C ++中,聚合可以可以通过定义属于真实实例的成员变量来实现,但更常见的是将它们定义为实例的指针或引用。熟人也可以通过指针和引用来实现。“
伙计们,请帮我弄清楚这里发生的事情...
答案 0 :(得分:-1)
是的,这两个术语组成和聚合周围存在很多混乱[还有很多要添加 Shared 和非共享聚合]。在经历了很多混乱并偏向于UML资源之后,我形成了以下观点[不需要被视为最终的或准确的]。
我采用的最简单且松散耦合的关系是 Association [它可以是单向或双向],其中对象具有其他对象的引用对象,但都独立生活。如果关联与特定的身份[在OO中,身份是每个实体对象的重要组成部分]相关联,则关联可以为合格的关联。客户帐户的accountNumber。
Aggregation 是由一个对象维护的(其他对象类型的,可以出于限制目的而组装)的集合。这两个对象仍然独立存在。例如田径队。同一名学生可以加入许多这样的团队,例如自行车队[骨料]等。删除田径队不会对大学记录中的每个学生入学有害[他们仍然存在]。这样的关系可以维持为团队侧的学生集合,或者作为团队中每个学生的田径队参考。这取决于更经常需要的应用程序导航性。
组成是更紧密的关系,其中容器对象完全容纳了所包含的对象,而所包含的对象与容器对象之间没有外部关系。我可以看到一个示例,该示例是“人员”和“地址”之间的关系,其中,每个人都要单独/重新输入地址。对于家庭成员,地址可能具有相同的逻辑平等,但从物理上平等。更改一个成员的地址不会影响其他成员[简单测试是-人员记录的DB列具有用于地址的扩展列作为人员表的一部分。]另一个示例是单次购买(行)项目购买和完整项目清单。删除帐单使每个条目变得没有上下文。
如果一个对象实例化并完全包含另一个对象[绝不允许外界通过任何方式获取其引用],我将其视为Composition。诸如在交互点处克隆对象而不是传递相同的引用之类的技术在这里可能会有所帮助。在关联或聚集的情况下,我们交换相同的参考。
容器是黑盒的重用,比白盒的重用(使用继承实现)更受青睐>)。大多数GOF模式建议容器的最佳组合,以实现重用,而继承则可以实现多态。例如如果是适配器模式,则 Object Adapter 优于 Class Adapter 。
在Java中实现所有这些风格(实现将是特定于语言的)有其自身的挑战,并非一帆风顺,尤其是 composition 。学习曲线上有一点,人们(至少我觉得)组成与内部类相同,内部类可以帮助我们实现它,但是简单地拥有内部班级不保证任何组成。