【问题标题】:Does UML shared aggregation imply absence of cycles?UML 共享聚合是否意味着没有循环?
【发布时间】:2022-01-15 19:56:55
【问题描述】:

总之

共享聚合似乎只是表达一种简单的关联。它显然是一种“建模安慰剂”,没有使用它的客观理由(除非在建模者之间就特定的附加语义达成一致的特定情况下)。

然而,一些消息来源声称共享聚合意味着实例的聚合图中没有循环。这将使聚合成为图形建模领域的强大工具。

但我在规范中找不到任何证据证明这些说法。我是否遗漏了一些间接证据(例如多个约束的相互作用)?

更多详情

报价

在他们的书统一建模语言参考手册,第 2 版中,Booch、Jacobson 和 Rumbaugh 声称(共享)聚合:

聚合和关联之间的区别通常是品味问题,而不是语义上的差异。请记住,聚合是关联。聚合传达了这样一种思想,即聚合本质上是其部分的总和。事实上,它添加到关联中的唯一真正语义是聚合链接链可能不会形成循环的约束,但了解这一点通常很重要。 (...) 尽管聚合附带的语义很少,但每个人都认为它是必要的(出于不同的原因)。将其视为建模安慰剂。

其他消息灵通的来源(例如uml-diagrams.org 和几篇学术论文)也认为有向无环图是理所当然的。

根据 UML 规范验证

这些书籍来自 2004 年,基于 UML 2.0。但这种说法的大部分内容仍然在 UML 2.5.1 规范中得到验证。共享聚合在其中以非常模糊的术语定义,与简单关联相比没有任何客观优势(第 112 页):

有时,Property 用于对使用一个实例将一组实例组合在一起的情况进行建模;这称为聚合。为了表示这种情况,Property 具有 AggregationKind 类型的聚合属性; (...)
...
分享: 表示该属性具有共享聚合语义。共享聚合的精确语义因应用领域和建模者而异。

另一个关于聚合的子句防止一些特殊的循环情况(p.200):

如果关联是二进制的并且另一端未标记为共享或复合聚合,则关联的一端属性只能标记为共享或复合聚合。

然而,在一般情况下,我没有发现任何证据表明“聚合链接链可能不会形成循环”。我也没有发现其他属性,例如传递性和反对称,可以推断出不存在循环。

UML 发明者的主张现在已经过时了吗?还是我错过了当前规范中允许得出此声明的某些内容?

【问题讨论】:

  • 我必须调查一下,但是从内存构成等于责任,这将排除一个循环。
  • 顺便说一句。说聚合是不正确的。你的意思是复合聚合?共享聚合甚至没有语义。您引用的书中的措辞可能已经过时了。
  • @qwerty_so 我的意思是共享聚合。除了引用之外,我已经更正了:Booch et al use "aggregation" for shared aggregation 和 "composition"。事实上,对于组合,它可以从生命周期责任中推断出来(甚至是白底黑字“组合可以在具有传递删除特征的有向无环图中链接”。如果该声明对于共享聚合仍然适用,那么最终会有合理地使用它,对树和其他具有自反关联的 DAG 进行建模,如 other question
  • 共享聚合的唯一限制是它只能用于二进制关联。
  • 如果你要找到它,你会找到什么样的证据?在实践中,如果聚合是其部分的总和,那么循环怎么可能呢?

标签: language-lawyer uml aggregation class-diagram


【解决方案1】:

您的分析是正确的。 UML 2 没有为共享聚合提供任何语义。

然而

UML 1 说:

两种聚合都定义了传递的反对称关系(即,实例形成有向非循环图)。

我不知道,为什么这没有被 UML 2 接管。我只能推测这是一个把婴儿和洗澡水一起扔出去的情况。有些人想明确表示,该规范将共享聚合的语义留给特定领域的解释。他们忘记了它实际上是有一些语义的,无论多么微弱。

我对此的看法

我们的情况是这样的:很多关于这个主题的书籍和网站,UML 1 规范和常识都同意,整体关系,无论是共享的还是复合的,都是非循环的。 UML 2 对此主题保持沉默。

因此,就我而言,我将共享聚合解释为非循环的。当然,我会在建模指南中记录这种解释。但是,我不认为它会让很多阅读我的图表的读者感到困惑,即使他们没有阅读我的指南,因为它符合他们的预期。

最后一点:除非确实需要,否则不要使用聚合。根据我的经验,这会引起很多不必要的讨论。

【讨论】:

  • 确实,UML 1.4,第 2.5.4.1 节特别指出:“一个关联可能代表一个聚合;即,整体/部分关系。(...) 可共享聚合表示弱所有权( ...)这两种聚合都定义了传递的反对称关系;也就是说,实例形成了一个有向的非循环图”。传递性和反对称性可以从整体/部分关系的原理中推导出来(即一个实例不能是它自己的一部分,但它的部分是部分的间接也是部分)。
  • 我相信这种损失不是偶然的,而是故意放宽规则以适应随着时间的推移出现的不同做法,其中一些与没有周期不相容。我特别认为共享聚合的使用过于频繁(而且形式上不合理)来代表object composition 反对继承。
【解决方案2】:

我认为我最喜欢的 UML 2.5 第 110 页对此非常清楚:

有时,Property 用于对使用一个实例将一组实例组合在一起的情况进行建模;这称为聚合。为了表示这种情况,Property 具有 AggregationKind 类型的聚合属性;代表整个组的实例由 Property 的所有者分类,代表分组的个人的实例由 Property 的类型分类。 AggregationKind 是具有以下文字值的枚举:

none Indicates that the Property has no aggregation semantics.
shared Indicates that the Property has shared aggregation semantics. Precise semantics of shared aggregation varies by application area and modeler.
composite Indicates that the Property is aggregated compositely, i.e., the composite object has responsibility for the existence and storage of the composed objects (see the definition of parts in 11.2.3).

复合聚合是一种强大的聚合形式,它要求一个部分对象一次最多包含一个复合对象。如果一个复合对象被删除,它的所有作为对象的部分实例都会被删除。

我强调。在任何情况下,共享聚合都无法运行,因为它的语义是未定义的。所以暗示只针对复合聚合。


标准是什么?

UML 有相当多的历史。那里有很多引用。随着 UML 的发展,只有少数人会得到更新。虽然 Booch 等人。发明了 UML,他们不再定义标准。这是由 OMG 完成的,他们发布了 ISO 标准(如果您愿意,您可以为此支付额外的费用)。相当多的术语具有古老的起源并且以一种或另一种方式已经过时。尽管如此,它们仍在被使用——而且是在错误的背景下。

标准完美吗?

绝对不是。它在不断发展,但仍然存在相当多的缺陷或误解。在我看来,在 UML 2.0 中引入共享聚合并不是一个好主意。定义每个定义都没有定义的东西似乎很奇怪。看看对这个概念的困惑证明我是对的。

【讨论】:

  • 感谢您的回答。但我正在仔细研究共享聚合,以找出其中是否存在一些可能与非常具体的案例相关的隐藏价值。规范没有定义精确语义这一事实并不意味着根本没有语义,也不意味着没有约束。例如,我们知道共享聚合仅允许用于二元关联,并且关联一侧的共享聚合意味着另一端不存在共享或复合聚合(第 200 页)。
  • 另外,除了这本书(UML的三位发明者写的)之外,我还发现了其他几个地方(例如uml-diagrams.org/aggregation.html,以及几篇学术论文),其中一个DAG用于共享假设聚合,以及不对称和传递性。 uml-diagrams 甚至在此基础上声称,如果 2 个类之间存在聚合,则在相反方向上不可能有不同的聚合。这让我觉得我可能错过了什么。
  • 嗯,戴姆勒和奔驰发明了汽车,但他们无法修理现代后裔之一。 OMG 定义标准,而不是发明者。 uml-diagrams 只是引用了发明者的书,而不是 OMG。最后,“它没有语义”当然没有任何解释。
  • 我有时想知道驾驶汽车会是什么样子,如果 OMG 制定汽车标准:“符合标准的汽车应该有一个闪光灯。闪光灯命令应该固定在方向盘的右侧,并且" ;-)
  • 他们可能会添加左/右转向选项以及中间转向。以防万一……
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 2014-08-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多