UML - 关联或聚合(简单的代码片段)

UML - association or aggregation (simple code snippets)

我快疯了,有多少书自相矛盾。

Class A {} class B {void UseA(A a)} //some say this is an association,
no reference is held but communication is possible
Class A {} class B {A a;} //some say this is
    aggregration, a reference is held

但是很多人说持有引用仍然只是一个关联,他们使用列表进行聚合 - 恕我直言,这是一样的,它仍然是一个引用。

我很迷茫,想弄明白这个问题

例如这里:http://aviadezra.blogspot.cz/2009/05/uml-association-aggregation-composition.html - Strong Association 和 Aggregation 之间有什么区别,在这两种情况下,作者都使用一个字段来存储引用..

另一个例子: 这据说是公会:

这就是聚合:

public class Professor {
  // ...
}

public class Department {
  private List<Professor> professorList;
  // ..

}

同样,有什么区别?这两种情况都是参考

参见上层建筑 2.1.1:

An association may represent a composite aggregation (i.e., a whole/part relationship). Only binary associations can be aggregations. Composite aggregation is a strong form of aggregation that requires a part instance be included in at most one composite at a time. If a composite is deleted, all of its parts are normally deleted with it. Note that a part can (where allowed) be removed from a composite before the composite is deleted, and thus not be deleted as part of the composite. Compositions may be linked in a directed acyclic graph with transitive deletion characteristics; that is, deleting an element in one part of the graph will also result in the deletion of all elements of the subgraph below that element. Composition is represented by the isComposite attribute on the part end of the association being set to true.

Navigability means instances participating in links at runtime (instances of an association) can be accessed efficiently from instances participating in links at the other ends of the association. The precise mechanism by which such access is achieved is implementation specific. If an end is not navigable, access from the other ends may or may not be possible, and if it is, it might not be efficient. Note that tools operating on UML models are not prevented from navigating associations from non-navigable ends.

您上面的示例处于不同的抽象级别。 Department/Course 是具体的编码 classes 而 Department/Professor 是一些抽象的业务级别。虽然没有很好的来源(我知道)解释这个事实,但 compositionaggregation 是您将仅在业务级别使用的概念,几乎从不在编码级别使用(下面的例外)。当您处于代码级别时,Association 两边都有角色名称,您的生活会好得多。角色本身是 class 属性的不同(/冗余!)呈现,指的是相反的 class.

聚合作为 classes 之间的强绑定被使用,例如在数据库建模中。在这里,只有当聚合之前已经全部删除时,您才能删除主(反之亦然:删除主将强制删除聚合)。聚合不能独立存在。您示例中的组合是(来自我的 POV)一个愚蠢的构造,因为它假装是某个星期的聚合。但这简直是无稽之谈。然后使用关联。只有在业务层面上,您才能尝试将(例如)机器零件建模为复合材料。在具体层面上,合成是一个无用的概念。

tl;博士;

如果 classes 之间存在关系,则将其显示为简单关联。添加诸如角色之类的详细信息将有助于讨论域详细信息。仅当在业务级别建模时才鼓励使用 composition/aggregation,在代码级别不鼓励使用。

我已经根据实际的 UML 规范而不是书籍作者的解释写了一篇关于 UML Association vs Aggregation vs Composition 之间差异的文章。

主要结论是

In short, the Composition is a type of Association with real constraints and impact on development, whereas the Aggregation is purely a functional indication of the nature of the Association with no technical impact.

导航性完全不同属性并且独立于 AggregationKind。

这个问题已经并且将会以许多不同的变体被问到很多次,因为很多人,包括许多知名开发人员,对这些术语的含义感到困惑,这些术语已经在 UML 中定义。因为这个问题被问了很多次,所以也被回答了很多次。看,例如this answer。我将尝试总结 UML 定义。

两个 class 之间的关联不是通过方法参数建立的,而是通过引用属性(class 属性)建立的,range/type 是关联的 classes。如果方法参数的类型是class,这不建立关联,而是建立依赖关系。

在查看关联的编码方式之前,必须先了解关联的逻辑概念。对象类型之间的关联 class 确定了这些类型的对象之间的关系。例如,关联 Committee-has-ClubMember-as-chair,在下面显示的 class 图中被可视化为一条连接线,可以 class 确定关系FinanceCommittee-has-PeterMiller-as-chair、RecruitmentCommittee-has-SusanSmith-as-chair 和 AdvisoryCommittee-has-SarahAnderson-as-chair,其中对象 PeterMiller、SusanSmith 和 SarahAnderson 的类型为 ClubMember,对象FinanceCommittee、RecruitmentCommittee 和 AdvisoryCommittee 的类型为 Committee.

关联始终通过引用属性进行编码,其中的 range/type 是关联的 class。比如像这样

class Committee { ClubMember chair; String name;}

在 UML 中,聚合和组合被定义为具有 class 化部分-整体关系的预期含义的特殊形式的关联。在聚合的情况下,与组合相反,整体的部分可以与其他整体共享。下面的聚合示例对此进行了说明,其中一门课程可以属于多个学位课程。

作品的定义特征是具有独占(或不可共享)的部分。组合可能会在整体和部分之间存在生命周期依赖性,这意味着当整体被破坏时,它的所有部分也会随之被破坏。但是,这仅适用于某些组合情况,不适用于其他情况,因此它不是定义性特征。下面是一个组合的例子,其中的部分(组件)可以从整体(组合)中分离出来,因此在它的破坏中幸存下来:

一方面,UML 是一种丰富的语言,这意味着描述同一事物的方法不止一种。这就是您发现不同书籍中描述的不同方式(以及关于 SO 的相互矛盾的答案)的原因之一。

但一个关键问题是 巨大 UML 和源代码之间的脱节。一个特定的源代码结构如何在 UML 中表示,反之亦然,根本不是 UML 规范的一部分。据我所知,只有一种语言 (Java) 有官方的 UML 配置文件,而且已经过时了。

因此,特定源语言结构的表示留给了工具供应商,因此有所不同。如果您打算从您的模型生成代码,则必须遵循供应商的约定。相反,如果您希望从现有源代码生成模型,您将获得基于相同约定的模型。但是,如果您将该模型转移到不同的工具(在最好的情况下这很困难)并从中生成代码,您将不会得到相同的代码。

在与语言和工具无关的模式下,可以找到我对在哪些情况下使用哪些关系的看法 here。值得重复的一点是,我不在源代码模型中使用无向关联,正是因为它们在实际代码中没有明显的对应物。如果在代码中 class A 引用了 class B,并且 B 也引用了 A,那么我改为绘制两个关系。