组合和聚合有啥问题?
Posted
技术标签:
【中文标题】组合和聚合有啥问题?【英文标题】:What's wrong with composition and aggregation?组合和聚合有什么问题? 【发布时间】:2020-01-24 13:30:37 【问题描述】:看到所有关于组合/聚合/关联的答案很奇怪。 谁/这些概念的来源是什么?
geeksforgeeks
wikipedia?!?!
stackexchange
最后是我可爱的 ***(至少我很高兴答案没有被标记为已验证)
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++中,聚合可以通过定义成员变量来实现,这些成员变量是真实的实例,但更常见的是将它们定义为实例的指针或引用。相识也是通过指针和引用来实现的。”
伙计们,请帮我弄清楚这里发生了什么......
【问题讨论】:
对象关系的许多概念都来自 UML。在实践中,我发现很少需要区分它们。关于高度评价的错误信息,欢迎使用 ***。 顺便说一句,这篇文章读起来更像是一个咆哮而不是一个问题。也许您可以准确指出您正在寻找什么样的答案。 您还应该尝试引用您提供的网站的相关部分,以便您的帖子更易于阅读。 【参考方案1】:是的,Composition 和 Aggregation 这两个术语有很多混淆[还有更多要添加 Shared 和 非共享聚合]。在经历了很多困惑和对UML资源的偏见之后,我形成了如下观点[不必认为是最终的或准确的]。
我采用的最简单且松散耦合的关系是 关联 [它可以是 单向 或 双向] 其中一个对象具有其他对象的引用对象,但都独立生活。关联可以是合格的关联,如果它通过特定的身份连接[在 OO 中,身份是每个实体对象的重要组成部分],例如客户帐户的 accountNumber。
聚合 是由一个对象维护的(其他对象类型的集合,可以为受限目的组合)。这两个对象仍然独立存在。例如田径队。同一个学生可以成为许多这样的团队的一员,比如自行车队 [聚合] 等等。删除田径队不会对大学记录中的每个学生条目造成伤害[它们仍然存在]。这种关系可以保持为团队方面的学生集合或作为团队成员的每个学生的田径队参考。它取决于应用程序更频繁地需要的可导航性。
Composition 是更紧密的关系,容器对象完全持有被包含的对象,被包含的对象在与容器对象的关系之外没有任何意义。我可以看到一个例子,即 Person 和 Address 之间的关系,我们为每个人保留单独/新的地址条目。对于家庭成员而言,地址可能具有相同的逻辑平等,但绝不是物理平等。一个成员的地址更改不会影响其他成员 [简单测试是 - 人员记录的数据库列具有作为人员表的一部分的地址的扩展列。] 另一个示例是单项(行)项目购买和完整的项目清单.删除账单使每个条目都没有上下文。
如果一个对象实例化并完全包含另一个对象[绝不允许外部世界以任何方式获取其引用],我会将其视为组合。在交互点克隆对象而不是传递相同的 ref 之类的技术在这里可能会有所帮助。在关联或聚合的情况下,我们交换相同的引用。
Containment 是 black-box 重用,优于 white-box 类型的重用(使用 inheritance)。大多数 GOF 模式都建议将包含用于重用和继承用于多态性的最佳组合。例如在适配器模式的情况下,Object Adapter 优于 Class Adapter。
在 Java 中实现所有这些风格(实现将是特定于语言的)有其自身的挑战并且不是很直接,尤其是组合。学习曲线上有一个点,感觉(至少我觉得)Composition 与 inner class 相同,inner class 可以帮助我们实现它,但只是有 inner类不提供任何组成保证。
【讨论】:
感谢您的回答。您能否也请分享您对表达对象与包含对象之间关系的术语的看法。 GoF 使用术语组合“通过组合对象来获得新功能以获得更复杂的功能”。我不明白为什么全世界都在使用 GoF 中的模式,却否认诸如组合、聚合和熟人(关联)之类的非常简单的术语? @Konstantin,我已经编辑了我的答案以适应您的上述观点。 UML 使用这些术语并清楚地区分它们。以上是关于组合和聚合有啥问题?的主要内容,如果未能解决你的问题,请参考以下文章