UML 聚合与关联
Posted
技术标签:
【中文标题】UML 聚合与关联【英文标题】:UML aggregation vs association 【发布时间】:2021-12-24 02:27:45 【问题描述】:我在这里,还有一个关于聚合和关联的问题。我想学习一些 UML 的基础知识,所以我开始阅读 Martin Fowler 的“UML 提炼”。我阅读了关于类的两章,我认为有一件事我无法完全掌握,那就是聚合与关联。书中有这样一段话:
在 UML 之前的日子里,人们通常对什么是聚合以及什么是聚合相当模糊。 协会。无论是否模糊,他们总是与其他人不一致。因此, 许多建模者认为聚合很重要,尽管出于不同的原因。所以UML 包括聚合(图 5.3),但几乎没有任何语义。正如 Jim Rumbaugh 所说,“想想看 作为建模安慰剂”[Rumbaugh,UML 参考]。
从我在 Stack Overflow 上阅读的这句话和主题中了解到,我使用这两种关系中的哪一种并不重要,它们的含义基本相同,或者是否存在使用聚合而不是关联的任何情况将是合理的和/或我不能在不改变类图的“含义”的情况下将一个更改为另一个?
我之所以这么问,是因为这本书是 2003 年出版的,在那几年里有些事情可能发生了变化。
【问题讨论】:
【参考方案1】:Rumbaugh 的陈述是最有说服力的,也是 Bob 叔叔的好建议。正如我所说的elsewhere,聚合在语义上是如此的弱,以至于没有提供任何实际有益的东西。它只有一个有效的极端情况(递归关系的非循环性),但很少有人知道和理解这一点。所以你最终不得不在 cmets 中指出。
我只是不使用它。并且从未感到任何损失。坚持简单的二元关联并专注于真正重要的事情——获得基数和正确的命名。与尝试决定不可判定的关联与聚合相比,您将从中获得更多。
第一次。
【讨论】:
你对作文链接有什么看法? @Dennis:与聚合不同,组合具有明确定义的语义,可以有效地将其与直接的二元关联区分开来。更多信息:***.com/questions/7834052/…【参考方案2】:也许这可以帮助你,但我认为你不会找到完美的解释:
区别之一是暗示。聚合表示整体/部分 关系,而关联则没有。然而,没有 两种关系的方式可能会有很大差异 实施的。也就是说,看代码会很困难 并确定一个特定的关系是否应该 聚合或关联。出于这个原因,它是相当安全的 完全忽略聚合关系。 [罗伯特 C. 马丁 | UML]
每种情况都有一个例子:
a) 关联是所有对象都有自己的关系 生命周期,没有所有者。让我们以老师为例 学生。多个学生可以与一个老师关联,并且 单个学生可以与多个老师关联,但没有 对象之间的所有权,并且都有自己的生命周期。两个都 可以独立创建和删除。
b) 聚合是关联的一种特殊形式,其中所有对象都有自己的生命周期,但有所有权和子级 对象不能属于另一个父对象。举个例子 部门和老师。一个老师不能属于 多个部门,但如果我们删除部门,教师对象 不会被破坏。我们可以考虑“有”关系。[Maesh | GeeksWithBlogs]
【讨论】:
有趣,但是关于第二个例子,我认为如果我们将聚合与关联交换,仍然不会有任何区别,这一切都归结为个人喜好和图表的可读性?跨度> 你如何判断一段关系是完整的还是部分的? @ChapMic "子对象不能属于另一个父对象" 这是完全错误的 :) 请看看***.com/questions/13935125/… 和这个en.wikipedia.org/wiki/Object_composition#Aggregation GeeksWithBlogs 参考资料(实际上)已损坏。它将重定向到 Geekswithblogs.net, the End of an Era.【参考方案3】:我倾向于使用聚合来显示与组合相同的关系,但有一个很大的区别:包含类不负责包含对象的生命周期。通常,将要包含的对象的(非空)指针或引用传递给包含类的构造函数。包含对象,在其生命周期的持续时间内,取决于存在的包含对象。没有包含的对象,包含的对象就不能(完全)完成它的工作。这是我对聚合隐含的“部分/整体”关系的解释。
【讨论】:
“没有包含的对象,包含的对象就无法(完全)完成它的工作。”关联和某些表单依赖项不也是这样吗?【参考方案4】:这个词经常被混淆。
聚合和组合是关联的一些类型。 在聚合和关联之间几乎没有区别 实现,并且许多将完全跳过聚合关系 他们的关系图。
你可以从这个类比中得到这个想法。
Class:A(person) 和 Class:B(car) 具有 关联关系,如果 Class:A 有一个 Class:B 声明,并且 Class:B(car) 对象不是必需的创建一个 Class:A(person) 对象。
Class:A(car) 和 Class:B(tyre) 具有聚合关系,如果 Class:A 有一个 Class:B 声明,并且 Class:B(tyre) 对象是必要创建一个 Class:A(car) 对象。
干杯!
【讨论】:
【参考方案5】:在 UML 中,聚合是未定义的,因为它们没有任何明确定义的语义。 聚合的一个有效用例是几个类的封装,如 Eric Evans 在“领域驱动设计”中所述。
例如汽车有四个***。 您可能想要计算每辆车的每个车轮驱动的总米数。 这个计算是由汽车实体完成的,因为它知道它有哪些***,而你并不关心哪些***属于哪辆车。
汽车是其所有部件(如车轮)的聚合根,您无法从聚合外部访问汽车的部件,只能访问根。
所以基本上一个聚合封装了一组彼此所属的类。
【讨论】:
UML 组合在语义上更接近 DDD 的聚合。 DDD 聚合具有一些非常明确的语义(实际上甚至比 UML 组合更强大)。肯定比 UML 聚合强得多。不幸的是条款不匹配:-(【参考方案6】:它们的意思不一样!我可以这样说:
关联关系:一个类引用另一个类。实际上它表明一个类与另一个类相关,但它们 不一定具有显示这种关系的属性...例如 'Teacher' 和 'Student' 班,虽然 'Teacher' 班没有 指学生的属性,但我们确实知道,实际上 老师确实有学生......而且“学校”班也有“老师”和 现在使这两个类与每个类相关的“学生”属性 其他。
聚合关系:一个类包含另一个类。但是如果容器(ClassRoom) 被销毁,则包含的(Chair) 不会。 实际上教室拥有椅子。聚合更强大 关系比关联关系。
这里还有一个关于它和整个 UML2.0 的教程,它解释了一切简单明了,你可能会发现它很有用:https://github.com/imalitavakoli/learn-uml2
TIP:另外让我提一下,因为关联关系在大多数时候类之间存在,我们有时不绘制它以防止不必要的复杂性。 p>
【讨论】:
【参考方案7】:在实现方面没有太大区别,但在概念上却有很大区别:聚合用于表达层次结构。当您使用组件的层次结构时,您需要在根界面中进行某些类型的操作:
在层次结构中查找子组件 在层次结构中添加/删除子组件 更改所有组件的通用属性 递归遍历层次结构(访问者模式) 重新配置层次结构和组件之间的链接(关联)在处理关联时,这些操作中的大部分都不需要。
【讨论】:
【参考方案8】:补充一点,我只建议从OMG 站点下载UML 规范:最佳参考,请参阅第 110 页。
None 表示该属性没有聚合语义。
Shared 表示该属性具有共享聚合语义。共享聚合的精确语义因应用领域和建模者而异。
Composite 表示属性是复合聚合的,即复合对象负责 组合对象的存在和存储(见11.2.3部分的定义)。
【讨论】:
以上是关于UML 聚合与关联的主要内容,如果未能解决你的问题,请参考以下文章