【问题标题】:Aggregation vs Composition聚合与组合
【发布时间】:2018-06-29 20:36:55
【问题描述】:

我想知道HumanDriver License 之间的关系是聚合还是组合?我很清楚RoomBuilding 关系是一个组合,ChairRoom 是一个聚合。但是Driver License 可以在没有Human 的情况下存在,但如果没有Human,它的存在就毫无意义。我被卡住了。

【问题讨论】:

  • 在这里阅读我的答案:stackoverflow.com/questions/48268986/…
  • @ThomasKilian 感谢您的回复。但是,我认为这并不能解决我的误解,根据您在答案中建议的解释Driver License 不会消失,如果所有者将失去它Human 所以我可以说这是聚合。但是Driver License 没有意义,例如,当它的Owner 将死时,License 的一个具体实体不能被另一个Human 使用,而Engine 的具体实体可以被另一个@987654338 使用@。事实上,Human 生命周期定义了 License 的生命周期,但 License 可以同时存在而没有 Human
  • @ThomasKilian 所以我们可以同时获得组合和聚合。但我想我的想法有误。真相在哪里?
  • 嗯,这里是安全方面。如果司机经过,许可证必须消失(失效)。所以你可以把它变成一个复合聚合。
  • 我应该说:“你必须把它做成一个复合...”

标签: uml entity-relationship


【解决方案1】:

我认为要回答这个问题的疑问,我们应该准确定义以下术语:

  1. 上下文
  2. 上下文中存在实例

如果上述术语定义准确,那么使用组合或聚合就没有任何疑问。

我的想法,如果我想问这个问题,在我对术语的具体定义中:

  1. 背景现实世界
  2. 实例的存在并销毁它:实例的有用性与它的存在无关。销毁它意味着使其无效。我们应该在所有者消失后使其失效。 (但我们不会立即这样做

因此,HumanDriver License 之间的关系不能现实世界上下文中构成。因为,通过销毁Human(消失,失去生命,...),我们不会立即销毁Driver License。它存在。

例如(在某些国家/地区),没有任何在线和最新的失效机制来使Driver License 失效立即,因此它可以在没有Driver 的情况下存在,直到我们使它无效。所以这段时间(从Driver消失到Driver License失效)它是存在的,Instance的有用性与它的存在性无关。再次注意:这是我对上下文和存在的定义。

编辑(基于@Thomas Kilian 的评论):
对于 Programming 及其技术(如 ORM)的上下文中的另一个示例,我们应该在删除 Driver 的实例后立即删除(无效)Driver License(我们可以在这个语境)。所以关系应该是一个组合。


最后:我想指出建模中术语(上下文和现有及其他相关术语)定义的重要性。如果我们没有准确地定义它们,那么问题就会出现许多解决方案(基于他们脑海中隐藏的定义)。

希望能提供帮助。

【讨论】:

  • 在现实世界中它不是复合的,但在 ORM 术语中,您可以将 Human*--License 设为复合以表示如果驱动程序死亡,则许可证必须被销毁。 OP 是在谈论模型,而不是现实世界(我猜)。
  • @ThomasKilian,你是绝对正确的。我想说的是上下文和其他术语定义的重要性
【解决方案2】:

由于驾驶执照不是人/人的一部分,而只是与她/他有关,因此它们之间既没有组合也没有聚合,而只是一个普通的关联。

Gholamali-Irani 的回答混淆了一个事实,即驾照必须与一个人相关联(即,相应的关联端具有完全相同的多重性)与许多组合物的(或有)特征具有不可分割的部分,并错误地断定该关联必须是一个组合。

在许多情况下,我们可能会怀疑关联是否是组合,将其建模为普通关联会更安全。

将关联(如Human-has-DriverLicense)建模为组合的唯一充分理由是当组件类型的实例(此处为驾驶执照)是没有自己身份的“弱实体”时.但是驾驶执照确实有自己的 ID,因此没有必要也没有任何好处,将它们建模为持有者的组成部分。

【讨论】:

  • 你的意思是它不能是HumanDriver License之间的聚合?
  • 可以是整体/部分关系。请阅读this paper中的整体关系的主要和次要特征
  • 另一个例子here,考虑DepartmentStaff之间的组合。我们可以说:Staff 也不是Department 的一部分。 但是这里有一个整体/部分的关系。
  • @Gholamali-Irani:将二进制关联(如 Humand-has-DriverLicense)建模为组合的唯一充分理由是当组件类型的实例(此处为驾驶执照)“弱”时实体”没有自己的身份。但是驾驶执照确实有自己的 ID,因此没有必要也没有任何好处,将它们建模为持有人的组成部分。
  • 在真实的单词上下文中我只说:它不能是一个组合。也许协会是对的。
【解决方案3】:

聚合意味着子级可以独立于父级而存在的关系。示例:班级(父母)和学生(孩子)。删除班级,学生仍然存在。

聚合示例

请务必注意,聚合链接并未以任何方式说明 A 类拥有 B 类,也没有说明两者之间存在父子关系(当父删除时,其所有子都将被删除)。其实,恰恰相反!聚合链接通常用于强调 A 类实例不是 B 类实例的专有容器,因为实际上同一个 B 类实例还有另一个容器。

作文示例:

我们应该更具体,并在除了 A 类和 B 类之间的部分关系之外的情况下使用组合链接 - 两者之间存在很强的生命周期依赖关系,这意味着当 A 类被删除时,B 类被删除结果也被删除了

组合暗示了一种关系,其中子不能独立于父而存在。示例:房屋(父)和房间(子)。房间不是独立于房子而存在的。


这里有一些额外的信息来阐述组合的概念

正如 Grady Booch 在 UML 用户指南中所述,Addison Wesley

但是,有一个简单聚合的变体 - composition - 确实添加了一些重要的语义。组合是一种聚合形式,具有强大的所有权和一致的生命周期作为整体的一部分。 具有非固定多重性的部分可能会在复合本身之后创建,但一旦创建,它们就会与它一起生死。这些部分也可以在复合体死亡之前显式删除复合。

此外,在复合聚合中,整体负责对其部分的处置,这意味着复合必须管理其部分的创建和销毁。例如,当您在窗口系统中创建框架时,您必须将其附加到封闭窗口。 同样,当您销毁 Window 时,Window 对象必须依次销毁其 Frame 部分。

(来源:UML 用户指南 - Grady Booch、James Rumbaugh、Ivar Jacobson、Addison Wesley 撰写)


总结一下 - (Read detailed Article)

总而言之,关联是一个非常通用的术语,用于表示在类上何时使用另一个类提供的功能。如果一个父类对象拥有另一个子类对象,并且如果没有父类对象,该子类对象就不能有意义地存在,我们说它是一个组合。如果可以,则称为聚合。

【讨论】:

  • “组合意味着孩子不能独立于父母而存在的关系。” 这是完全错误的。 UML 明确指出,组合并不意味着没有整体就不能存在部分。
  • "复合聚合是一种强聚合形式,它要求一个部分对象一次最多包含在一个复合对象中。如果一个复合对象被删除,其所有作为对象的部分实例都将被删除。连同它一起删除。”摘自 - 第 110 页,OMG 统一建模语言规范,版本 2.5,2015 -omg.org/spec/UML/2.5
  • 我不确定您是否完全理解您从上面的 OMG 规范中引用的注释? ---- 它只是意味着“但是,可以从合成中单独删除一部分,而不必删除整个合成。”
  • 我只能同意您对与构图相关的概念的解释非常“新”,并且与业内大多数其他人、OMG 规范和维基百科不同。
  • 我不会说“如果 0 下限无效,或者它只是一个明显的错误”(尽管我个人会尽力避免它),或者另一方面考虑“组成意味着孩子不能独立于父母而存在的关系。” UML User's Guide 中的 3 Amigos 所建议的“只是一个简单的权利”,我们必须盲目地遵循,没有任何实际考虑;这可能会导致非建设性和绝对的二元对立。
猜你喜欢
  • 1970-01-01
  • 2010-10-18
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 2021-01-15
  • 1970-01-01
相关资源
最近更新 更多