UML共享聚合是否意味着没有循环?

3

简而言之

共享聚合似乎只是一个简单的关联。除了在模型师之间同意使用特定的附加语义的特定情况下,它显然是一种“建模安慰剂”,没有使用它的客观理由。

然而,有几个来源声称,共享聚合将意味着实例聚合图中不存在循环。这使得聚合成为图形建模领域中的强大工具。

但我在规范中找不到这些声明的任何证据。我错过了一些间接证据吗(例如多个约束的相互作用)?

更多细节

引用

在他们的书《统一建模语言参考手册,第二版》中,Booch、Jacobson和Rumbaugh对(共享)聚合表示:

聚合和关联之间的区别往往只是品味问题,而不是语义上的差异。请记住,聚合就是关联。聚合传达的想法是,聚合体本质上是其部分的总和。事实上,它所添加的唯一真正的语义是,聚合链接的链不能形成循环,这通常是很重要的,然而……尽管聚合附加了很少的语义,但每个人都认为它是必要的(出于不同的原因)。把它看作是一种建模安慰剂。

其他相当知情的来源(例如uml-diagrams.org和几篇学术论文)也将有向无环图视为已知事实。

根据UML规范进行验证

该书出版于2004年,基于UML 2.0。但是在UML 2.5.1规范中,大部分这种说法仍然得到证实。其中非常含糊地定义了共享聚合,并且与简单关联没有任何客观优势(第112页):

有时使用属性来模拟一个实例用于组合一组实例的情况;这称为聚合。为了表示这样的情况,属性具有聚合属性,类型为AggregationKind; (...)
...
shared: 指示该属性具有共享聚合语义。共享聚合的精确定义因应用领域和建模者而异。

关于聚合的另一个条款防止了一些特殊的循环情况(第200页):

如果协会是二元的且另一端没有标记为共享或组合聚合,则协会的端属性只能标记为共享或组合聚合。

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

UML发明者的说法现在已经过时了吗?还是我错过了当前规范中允许推导这种说法的内容?


我得仔细研究一下,但从记忆中来看,组合等于责任,这将排除一个循环。 - qwerty_so
@qwerty_so 我的意思是共享聚合。我已经更正了,除了引用:Booch等人使用“聚合”表示共享聚合和“组合”。确实,对于组合,可以从生命周期责任中推断出来(甚至在黑白上写着“组合可以与具有传递性删除特征的有向无环图链接”。如果该语句仍然适用于共享聚合,则最终将有一个合理的用途,以模拟树和其他具有自反关联的DAG,如此其他问题 - Christophe
共享聚合的唯一限制是它只能用于二元关联。 - Geert Bellekens
是的,图应该在实例级别上是无环的,而不一定在类级别上。但我不明白为什么与简单关联相比似乎没有增加价值。规范说:“共享聚合的精确语义因应用领域和建模者而异”。作为一个建模者,关联和共享聚合给我提供了不同的表示关系的方式,即使差异的精确语义留给我自己决定。我可以使用它们来传达对实现细节(如生命周期)的特定意图。 - Dave S
这就是为什么我喜欢强调,如果没有明确的“统一”理解何时使用聚合和关联,那么辩论是毫无价值的。最后,当人们实现模型时,如果他们意识到自己实现的是关联而不是聚合,而图表上却标记为聚合,那么会产生很多混乱。 - Christophe
显示剩余7条评论
2个回答

3
你的分析是正确的。UML 2没有赋予共享聚合任何语义。
然而,UML 1表示:
两种类型的聚合都定义了一种传递性、反对称的关系(即实例形成一个有向的非循环图)。
我不知道为什么这个规定没有被采用到UML 2中。我只能猜测这是因为一些人想要明确规范留给领域特定解释的共享聚合语义,并且他们忘记了它实际上应该具有一些弱的语义。
我的看法是这样的:大量介绍这个主题的书籍和网站、UML 1规范和常识都认为整体-部分关系,无论是共享还是组合,都是非循环的。而UML 2对此保持沉默。
因此,我会把共享聚合解释为非循环的。当然,我会在建模指南中记录这种解释。但即使读者没有阅读我的指南,我也不认为这会让他们困惑,因为这符合他们的预期。
最后需要注意的是:除非你真的需要,否则不要使用聚合。根据我的经验,它会引起许多不必要的讨论。

确实,UML 1.4第2.5.4.1节指出:“关联可以表示集成;也就是整体/部分关系。(...)可共享聚合表示弱拥有(...)两种类型的聚合定义了一个传递性、反对称关系;也就是说,实例形成了一个有向非循环图。”由于整体/部分关系原则,可以推导出传递性和反对称性属性(即实例不能是自身的一部分,但它的部分间接地也是部分)。 - Christophe
我相信这种损失不是偶然的,而是有意放松规则以适应随着时间推移出现的不同实践,其中一些与无周期性不兼容。我特别想到的是过于频繁(并且在形式上没有理由)使用共享聚合来代表对象组合而不是继承。 - Christophe

1
我认为UML 2.5中第110页是非常清晰的:

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

none 表示该属性没有聚合语义。
shared 表示属性具有共享聚合语义。共享聚合的精确语义因应用领域和建模器而异。
composite 表示属性被组成聚合,即复合对象对组成对象的存在和存储负责(请参阅11.2.3中部件的定义)。

组合聚合是聚合的一种强形式,它要求在任何时间内,一个部分对象只能包含在最多一个组合对象中。如果删除组合对象,则与之相关的所有对象都将被删除。

强调是我的。由于共享聚合的语义未定义,因此在任何情况下都不使用它。所以这个含义只是针对组合聚合的。


什么是标准?

UML有相当多的历史。而且有很多引文。只有极少数随着UML的发展得到更新。尽管Booch等人发明了UML,但他们不再定义标准。这是由OMG完成的,并发布ISO标准(如果您愿意,可以额外支付费用)。相当多的术语具有古老的起源并且已经过时。尽管如此,它们仍在使用中 - 而且在现在的错误上下文中。

标准完美吗?

绝对不是。它正在不断发展,并仍然存在一些缺陷或误解。在我看来,UML 2.0中引入共享聚合不是一个好主意。定义没有定义的东西似乎很奇怪。而且看看这个概念的混淆证明了我的正确性。


谢谢您的回答。但我正在研究共享聚合,以找出其中是否存在某些隐藏的价值,这可能与非常特定的情况相关。规范没有定义精确的语义并不意味着根本没有语义,也不意味着没有约束条件。例如,我们知道共享聚合仅允许二元关联,并且在关联的一侧进行共享聚合意味着在另一端不存在共享或组合聚合(第200页)。 - Christophe
此外,除了由UML三位发明者编写的书籍之外,我还在其他几个地方(例如https://www.uml-diagrams.org/aggregation.html以及几篇学术论文)中发现了共享聚合的DAG假设,以及不对称性和传递性。uml-diagrams甚至基于此声称,如果两个类之间存在聚合,则不能在相反方向上存在不同的聚合。这让我想到可能有些遗漏。 - Christophe
德国戴姆勒和奔驰发明了汽车,但他们可能无法修理现代后代之一。OMG定义了标准,而不是发明者。UML图仅引用发明者的书籍,而非OMG。最后,“它没有语义”当然没有解释。 - qwerty_so
有时我在想,如果OMG制定了汽车标准,那开车会是什么样子:“符合标准的汽车应该有一个方向指示器。方向指示器按钮应该固定在方向盘右侧,上面带有空心的方向指示器符号。关于闪烁的确切语义以及操作方向指示器按钮触发左或右信号的方式都故意不作规定。”;-) - Christophe
他们可能会添加左/右转向选项以及中间转向选项,以防万一... - qwerty_so

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