【发布时间】:2020-02-16 23:18:29
【问题描述】:
我已经阅读了很多关于对象关系的理论,但我仍然很难理解关联和聚合是如何分离的从实现的角度来看。 在这两种情况下,您都将对象 B 作为对象 A 中的数据成员,在那里它作为引用存在(与组合不同,它通过值存在于那里)。那么这两种情况有什么区别呢? 我在某处读到一些 Java 大师认为聚合是一个完全抽象的概念,一个“安慰剂”案例,从实现/语法的角度无法区分(从关联),是对的还是我错过了什么?
【问题讨论】:
我已经阅读了很多关于对象关系的理论,但我仍然很难理解关联和聚合是如何分离的从实现的角度来看。 在这两种情况下,您都将对象 B 作为对象 A 中的数据成员,在那里它作为引用存在(与组合不同,它通过值存在于那里)。那么这两种情况有什么区别呢? 我在某处读到一些 Java 大师认为聚合是一个完全抽象的概念,一个“安慰剂”案例,从实现/语法的角度无法区分(从关联),是对的还是我错过了什么?
【问题讨论】:
我同意从实现的角度来看,关联和聚合看起来是一样的——就像你提到的,在这两种情况下,其中一个对象是另一个对象的数据成员。
我的理解是,您所询问的实现差异不会发生在对象级别,而是发生在应用程序设计级别:
如果通过实现差异您了解代码本身(对象放置在另一个中的方式),那么没有区别。
编辑 -> 附加说明如下:
我可能还不够清楚 - 我的意思是在这种情况下,实现可以在两个层面上考虑:
在类中表示对象的代码(保存对象引用的字段)
更广泛的代码(对象如何在其他类中使用或对象之间的依赖关系如何表示)
这两者都可以理解为实现,但是在不同的抽象级别上 - Aggregation 和 Composition,但对象关系在多个类中实现的方式会有所不同。
【讨论】:
正确地说:UML 术语聚合(您可能指的是)是composite aggregation。 UML 2.5 的第 110 页说:
composite- 表示Property是复合聚合的,即复合对象负责复合对象的存在和存储(参见11.2.3中的部件定义)。
如果您指的是共享聚合,请参见相同的 p。 110:
shared- 表示该属性具有共享聚合语义。共享聚合的精确语义因应用领域和建模者而异。
tl;dr
区别很简单。如果聚合对象说再见,则必须销毁复合(聚合)对象。关联的对象不关心(或者引用对象不会尝试杀死它)。
对于共享聚合:发明您自己的定义并将其连同其用法一起发布。
【讨论】:
聚合与关联的实现通常没有区别,因为它们的语义差异通常与应用代码无关。
聚合是与部分-整体-关系的预期含义的特殊关联形式,其中整体的部分可以与其他整体共享。例如,我们可以对 DegreeProgram 和 Course 类之间的聚合建模,如下图所示,因为课程是学位课程的一部分,并且课程可以在两个或多个学位课程之间共享(例如工程学位可以与计算机科学学位共享 C 编程课程)。
以这种方式对DegreeProgram 和Course 之间的特殊关系进行建模传达了一些预期的含义,但不一定,通常也不会反映在实现代码中,可能如下所示:
class DegreeProgram {
private List<Course> courses;
...
}
【讨论】: