UML符号 - 聚合/组合与“纯粹”的关联

6
我最近花了很多时间对各种软件组件进行详细的UML设计,然后编写代码。回顾我最近完成的工作并将其与我第一次学习UML时的情况进行比较,我发现我现在几乎只使用聚合和组合关系,而几乎放弃了“普通”的非定向/有向关系。当然,我仍然使用泛化和实现,但这些与上述关系明显不同,不属于本问题的范畴。
在我看来,聚合/组合意味着“普通”关联的含义以及更多的含义。聚合和组合自然地暗示了一个方向,并且任何现代UML程序仍然允许您定义聚合/组合关系的多重性并为关系应用动词。在这一点上,我认为普通关联的作用很小。
我知道有些人难以理解聚合和组合之间的区别。早期,我也有一些困难,我相信这种混淆是我使用普通关联的原因之一。现在我已经到了这样的地步,我认为几乎没有使用普通关联的必要,实际上我不喜欢看到它们被使用,因为我认为它们会留下一些问题(特别是两个对象之间的强或弱生命周期关系)。我认为普通关联的唯一实际用途是当您对手头的问题的理解还不够发展时,无法确定聚合和组合之间的生命周期差异。在这种情况下,最好至少“显示”关系存在,然后在更好地了解手头问题时再适当地更改它。
长话短说,我认为大多数人使用普通关联的时间,他们可以更准确地描述为聚合,有时也可以描述为组合。我的想法非常错误吗?我错过了什么吗?让我听听你的意见!
5个回答

3
实际上,UML类模型中的大多数关联都不是聚合或组合。例如,类之间的关联PublisherBook用于将一个出版商出版的书籍分配给该出版商,既不是聚合也不是组合,因为出版商出版的书籍不是该出版商的部分或组成部分。
聚合是一种特殊形式的关联,其意图是表示整体和部分之间的关系,但没有精确的语义(UML规范说:“共享聚合的精确定义因应用领域和建模者而异”)。例如,我们可以在类CarEngine之间以及类CourseLecture之间建模聚合,因为发动机是汽车的一部分,讲座是课程的一部分。
组合(在UML规范中也称为“复合聚合”)是聚合的一种特殊形式,其中组件实例最多同时是一个聚合实例的一部分(即它不能在多个聚合之间共享)。这意味着CarEngine之间的聚合是组合(因为一个发动机不能在同时被两辆汽车共享),而CourseLecture之间的聚合不一定是组合,因为一个讲座可以在两个课程中共享(例如数据库管理课程和软件工程课程可以共享UML讲座)。这意味着组合关联端点的多重性在聚合方面可能为1或0..1,而在非复合聚合的情况下可能也为*。
除了组成部分具有排他性的主要特征之外,组合还可能伴随着聚合与其组成部分之间的生命周期依赖关系,意味着当聚合被删除时,其所有部分也将被删除。然而,这仅适用于某些组合的情况,而不适用于其他情况,因此不是定义特征。UML规范说明:“在删除组合实例之前,可以从组合实例中删除零件,因此不会作为组合实例的一部分被删除。”在我们的汽车-发动机组合示例中,显然发动机可以在汽车被摧毁之前从汽车上拆卸下来,在这种情况下,发动机不会被摧毁并可重新使用。

1
你对组合的理解(或者至少是你从UML规范中引用的内容)是错误的。请参考UML超级结构规范,v2.4.1,第38页上写道:“..复合聚合是一种强聚合形式,要求一个部分实例在同一时间内只能包含在最多一个复合体中..”。它在哪里说“..是最多一个聚合的一部分..?” - xmojmr
@xmojmr:我的理解和引用都没有错。我只是把“aggregate”用作“composite”的同义词。因此,请取消您不合理的负评。 - Gerd Wagner
1
你对“aggregate”一词作为“composite”的同义词的使用是有问题的。它们不是同义词,而你得出了一个结论,给人留下你在引用UML规范的印象。然后你将你的错误引用作为反对http://stackoverflow.com/a/25236323/2626313的理由。你简化的同义词“引用”并不适用。如果你改变你的投票并改进你的观点,我可以改变我的投票。你正在从一本书中“引用”一些东西,而这本书根本没有包含你的引用。我在你的评论后重新审查了我的答案。你能做同样的事吗? - xmojmr

2
香草关联、聚合和组合有时被解释为以下语义:
  • 香草关联:一个对象“知道”一个或多个其他对象
  • 聚合:一个对象“拥有”一个或多个其他对象
  • 组合:一个对象“由”一个或多个其他对象组成 - 子对象不能没有组成容器

大多数聚合和组合的区别围绕着这个问题展开:“如果主对象消失了 - 部分对象会发生什么?”。

因此,想法是使用其中三个选项之一来描述像“级联删除”这样的完整性约束。UML对此有三种不同的符号:

  • 没有符号 - 香草关联
  • 菱形 - 聚合
  • 填充的菱形 - 组合

这三个选项的问题在于,它们的语义对于现实生活中的情况并不够精确,特别是当您看到随时间变化的情况时。

例如,试图回答简单的问题“我的汽车有多少个轮胎?”将导致不同的答案:

  • 4个永久安装在我的汽车上的轮子
  • 1个备用轮胎,我可能会在紧急情况下使用
  • 4个轮子,它们是我的夏季或冬季轮胎,不会在其他季节安装在车上

Wheels of a car

看见

当汽车消失时,这些轮子中有多少会消失? 如果您尝试使用 UML 提供的三个符号来建模这种情况,您将最终需要进行大量的讨论和协商,以确定您的模型真正意味着什么。我认为最好永远不要使用聚合和组合符号,而是始终使用几行文本尽可能精确地描述关联语义。这样,您可以向阅读您的模型的人清楚地说明您想要的内容。 我认为甚至可以写“汽车是由包括轮子在内的零件组成的”。

但现在,您没有使用组合符号,而是真正引用了组合某物的行为。

参见: http://de.wikipedia.org/wiki/Assoziation_%28UML%29#Aggregation_und_Komposition(德语)

1
在类图上,您正在考虑类之间的静态关系。您可能不需要在类图上考虑这些关系的行为方面,因为这只会使问题更加复杂,并且是过度分析的证明。(当然,这是我的个人意见)

1
当你说“香草关联”的唯一实际用途是在你对手头问题的理解还不够发展以确定生命周期差异并表明关系存在时,你说得很对。当你更好地理解手头的问题时,你可以回来适当地改变它。 UML元模型定义了聚合和组合作为关联的扩展。关联可以被认为是域对象之间未经过精炼的关系,就像域对象是未经过精炼的类一样。我通常在域建模阶段使用简单的关联,并在解决详细的类模型时将其细化为组合或聚合。

1
讲解得非常清晰简洁,很有道理。谢谢Martin! - James
1
该论点是完全错误的:聚合和组合扩展了 UML 中关联的概念,并不证明“关联是领域对象之间未经过精细处理的关系”的观点是正确的。有许多情况下,一个关联既不是聚合也不是组合。请见下面我的回答。 - Gerd Wagner

0

聚合和组合都意味着关系中的一个参与者“支配”另一个(在组合中支配更强),而普通关联没有这种暗示。因此,当关系中的两个参与者具有相同的重要性时,我使用普通关联。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接