具有聚合和组合的 UML 循环引用
UML Circular reference with both aggregation and composition
前几天有朋友向我指出我对UML中的组合有错误的认识。她是完全正确的,所以我决定找出我可能还错了什么。现在,还有一件事我有疑问:我的代码库中有一个循环依赖,我想以 UML 形式呈现。但是如何。
在我的例子中,以下是正确的:
- A和B都有C的列表
- C 引用了 A 和 B 以从中获取信息。
- 如果 A 或 B 不存在,C 也不存在
- 从A中删除C后,A和B仍然存在and/or B
为了对此建模,我提出了以下 UML(我暂时省略了多重性,以免挤满图表。)
我的问题是,这是模拟这种关系的正确方法吗?
去掉空心菱形,让它们成为正常的联想。这些不是共享的聚合,而是简单的关联。复合聚合没问题
一般来说,显示聚合根本没有太多附加值。语义附加值很低。在过去,这是一个很好的提示,可以帮助垃圾回收处理不需要的对象。但是现在几乎所有的目标语言都有内置的高效垃圾收集器。只有在您想要显式删除聚合对象的情况下,您才应该使用复合聚合。
问题
需要记住的一些事实:
- 默认多重性使您的模型无效。一个class只能由一个其他class组成。当您不指定多重性时,您会得到 [1..1]。该默认值令人难过,但却是事实。
- UML 规范没有定义开放式菱形聚合的含义。
- 您的模型有很多重复的属性。不需要属性隔间中的任何属性,因为每个关联的末尾已经有未命名的属性。
更正
这里对您的模型进行了修改,使其更正确:
注意以下几点:
- 关联之间的异或约束意味着一次只能存在其中一个。
- 不幸的是,多重性允许
C
的实例存在而不是由 A
或 B
组成。 (请参阅下面重新设计的模型。)
- 所有关联末尾的 属性 名称明确命名了模型中未命名的内容。 (我还试图在 属性 名称中指明用途。)
- 导航箭头可以在不求助于重复属性的情况下防止多个不需要的属性。
建议设计
如果我正确理解您的模型的含义,我可能会按照以下方式将实施反转为设计:
注意以下几点:
- Class
D
是抽象的(class 名称以斜体显示),这意味着它不能有直接实例。
泛化集表示:
- 一个实例不能被class乘以
A
和B
。 (即,A
和 B
是{不相交的}。)
D
的实例必须是子class之一的实例。 (即,A
和 B
是{完整},称为 covering axiom。)
- 子class从class
D
继承了ownedC
属性。
- 组合 class 现在可以有多个 [1..1],这不再允许
C
的实例在不由 A
或 A
组合的情况下存在B
.
前几天有朋友向我指出我对UML中的组合有错误的认识。她是完全正确的,所以我决定找出我可能还错了什么。现在,还有一件事我有疑问:我的代码库中有一个循环依赖,我想以 UML 形式呈现。但是如何。
在我的例子中,以下是正确的:
- A和B都有C的列表
- C 引用了 A 和 B 以从中获取信息。
- 如果 A 或 B 不存在,C 也不存在
- 从A中删除C后,A和B仍然存在and/or B
为了对此建模,我提出了以下 UML(我暂时省略了多重性,以免挤满图表。)
我的问题是,这是模拟这种关系的正确方法吗?
去掉空心菱形,让它们成为正常的联想。这些不是共享的聚合,而是简单的关联。复合聚合没问题
一般来说,显示聚合根本没有太多附加值。语义附加值很低。在过去,这是一个很好的提示,可以帮助垃圾回收处理不需要的对象。但是现在几乎所有的目标语言都有内置的高效垃圾收集器。只有在您想要显式删除聚合对象的情况下,您才应该使用复合聚合。
问题
需要记住的一些事实:
- 默认多重性使您的模型无效。一个class只能由一个其他class组成。当您不指定多重性时,您会得到 [1..1]。该默认值令人难过,但却是事实。
- UML 规范没有定义开放式菱形聚合的含义。
- 您的模型有很多重复的属性。不需要属性隔间中的任何属性,因为每个关联的末尾已经有未命名的属性。
更正
这里对您的模型进行了修改,使其更正确:
注意以下几点:
- 关联之间的异或约束意味着一次只能存在其中一个。
- 不幸的是,多重性允许
C
的实例存在而不是由A
或B
组成。 (请参阅下面重新设计的模型。) - 所有关联末尾的 属性 名称明确命名了模型中未命名的内容。 (我还试图在 属性 名称中指明用途。)
- 导航箭头可以在不求助于重复属性的情况下防止多个不需要的属性。
建议设计
如果我正确理解您的模型的含义,我可能会按照以下方式将实施反转为设计:
注意以下几点:
- Class
D
是抽象的(class 名称以斜体显示),这意味着它不能有直接实例。 泛化集表示:
- 一个实例不能被class乘以
A
和B
。 (即,A
和B
是{不相交的}。) D
的实例必须是子class之一的实例。 (即,A
和B
是{完整},称为 covering axiom。)
- 一个实例不能被class乘以
- 子class从class
D
继承了ownedC
属性。 - 组合 class 现在可以有多个 [1..1],这不再允许
C
的实例在不由A
或A
组合的情况下存在B
.