UML关联类在多个关系中的应用

6
我正在使用UML制作类图,但找不到关于这个主题的信息。 我可以在多个关联类之间拥有一个类吗? 这里有一个例子: 消息应该是用户和组之间的关联类,但也是用户和频道之间的关联类。 这种情况是否允许或者还有其他方法可以实现此功能? 谢谢!

警告:“我可以将同一关联类与多个关系相关联吗?”这句话是错误的,您至少必须删除“关联”,并在标题中也是如此。您需要像“我可以在几个关联类中拥有一个类”这样的内容。 - bruno
3个回答

2

什么是关联类?

当查看关联类的图形标记时,我们可能会误认为关联类只是附加到关联的类。

但实际上,关联类既是关联又是类:

UML 2.5.1 / 第11.5.3.2节:关联类是声明具有自己一组特征的关联。关联类既是关联又是类,并保留了两者的静态和动态语义。

因此,在建模语义中,除了符号外,您无法将关联类与相应的关联分开。如果您还不确定,请参阅规范中的下一句话:

关联类描述了一组对象,每个对象都共享由关联类作为类的特征、约束和语义所隐含的规格,并对应于唯一的链接,该链接将关联类作为关联的一种实例化。

(链接是关联的实例,对应于具有“每个成员端点的一个值”的元组)

关联类二元性的后果是什么?

结果是,同一关联类不能以多个不同的形式存在,每个形式都将关联不同的类集。
虽然符号中没有阻止您添加点线来似乎“连接”同一类到两个不同的关联如布鲁诺所解释的那样,但这种符号不符合有效的UML语义。
备选方案
您的问题强调了一个有趣的设计问题。幸运的是,有很多解决方法。例如:
1. User类与抽象的Destination类相关联。Message将是关联类。 Destination将被专门化为Group和Chanel,两者都会继承关联(无需在图形上重复关联)。 (编辑:正如Axel Scheithauer在评论中强调的那样,关联和关联类是相同的,它们必须具有相同的名称)

enter image description here

忘掉关联类。将Message变成普通类,并与User关联。同时,也将其与GroupChanel关联。如果必要的话,在这两个关联之间添加一个{xor}约束,以表示它们是互斥的。

enter image description here

您目前只与“Group”建立了多对多关联,而没有与“Channel”建立关联,这表明存在一些显著的差异,并且更支持第二种情况而不是第一种情况。
无论关联类型如何,您当前的模型都引发了一些问题,涉及与“Group”建立的多对多关联:
- 您是否意味着多个用户可以向多个组发送相同的消息? - 还是指用户可以向一个群发送消息,而该群由多个用户组成?
在后一种情况下,您应该选择两个不同的关联:一个用于发送关联,另一个用于组成员资格关联(请参见上面的红色关联图表)。

1
你解释得很正确,关联类指定了一个既是关联又是类的对象。然而,在你的示例图中,你展示了两个不同的名称sendsmessage。由于它们是同一个元素,它们只能有一个名称。 - Axel Scheithauer
@AxelScheithauer 当然,您是完全正确的!我使用了OP问题中提供的元素来帮助映射。我已经进行了编辑,以引起您的重要评论的注意,并解决图形符号中的问题。 - Christophe

1
这是一个非常有趣的问题。
formal/2017-12-05中,第199页的图11.25"关联",第200页开始的“11.5.3.2关联类”以及第220页开始的“11.8.2关联类[类]”中都没有说明一个类不能用于多个关联类,因此我认为可以这样做。

enter image description here

但是要注意,类的名称和关联的名称必须相同,来自 formal/2017-12-05 § 11.5.3.2 Association Classes第200页:

关联和类都是分类器,因此具有一组共同属性,例如能够拥有特征,具有名称等。这些属性从相同的构造(分类器)中继承,并且不会重复。因此,关联类只有一个名称,并且具有为类和关联定义的特征集。

那么如果您想创建关联类,则不能将类命名为Message,并且关联也不能命名为sends

Note类和Association类都是NamedElement(第47页的“7.8.9 NamedElement [抽象类]”),一个给定名称可以用于多个NamedElement,但是要共存于同一Namespace中,两个NamedElement必须是可区分的。从formal/2017-12-05第49页的“7.8.9.7 Operations”中:

isDistinguishableFrom(n : NamedElement, ns : Namespace) : Boolean
isDistinguishableFrom()查询确定两个NamedElements是否可以在命名空间中逻辑上并存。默认情况下,如果(a)它们具有不是彼此类型的任何类型或(b)它们具有不同的名称,则两个命名元素是可区分的。

然后两个关联Message必须位于不同的命名空间中,因为它们具有相同的名称。


1
非常感谢,这解决了我的问题 :) 我都快疯了,一直在找这个! - tremon
@tremon,不用谢,希望我的回答是正确的,等待其他人的反应。 - bruno
@tremon,你的问题有一个对应的问题,我发布了这个问题是否可以在多个关联类中使用关联? ;-) - bruno
2
一个AssociationClass仍然是一个Association。因此,相同的规则适用:二元Association或AssociationClass连接两个类。这意味着您的模型不可能。您可以拥有一个三元Association,但那将是完全不同的事情,具有完全不同的符号表示(一个白色菱形连接到所有三个类,并带有虚线连接到AssociationClass的类部分)。因此,我认为@JimL的答案是正确的方法。 - Axel Scheithauer
@bruno:在你的图表中,有两条类似于关联的线和一个矩形类似于一个类,用虚线连接。如果只有一条虚线,那么它就是关联类的符号。我不知道你想用你的符号表达什么。既然你连接了三个类Group、Channel和User,我想知道你是否考虑到了三元关联类。 - Axel Scheithauer
显示剩余5条评论

0

如果你想让消息成为连接用户到组和频道的 UML Association Class 的实例,那么可以将 Message 协会的一端属性连接到一个 UML 类的实例,该类是 Group 和 Channel 的联合体。

要构建联合类,将其作为两个 UML Generalization 实例的一般端,并将其设置为抽象。一个 generalization 的具体端点将是 Group,另一个则是 Channel。为了更清晰明了,将这些 generalization 放入一个 {complete} 的 UML Generalization Set 实例中。


1
那是我曾经考虑过的事情,但问题在于组和通道在它们的关系中具有不同的基数。 - tremon
1
可以通过专门化继承的关联来实现不同的多重性。是的,这是可能的。 - Axel Scheithauer
1
你为什么要首先使用AssociationClasses?根据你的描述,消息是从一个User实例流向一个Group实例的信息。对于这种情况,AssociationClasses不是正确的方式。相反,“message”将是一个独立的类,具有与“User”和抽象超类的关联。 - Axel Scheithauer
1
可以使用AssociationClass来处理message,但这样做会很麻烦。而且你的图表中还需要使用Associations。当两个实例之间的链接需要具有属性时(例如,公司-人员可能需要合同开始日期),使用AssociationClasses是有用的。即使如此,它们通常也可以用普通类和两个关联来替代。 - Axel Scheithauer
(我在回答的同时干涉了你的回答,希望这不是问题)如果您想让“Message”成为UML关联类的实例:这不是OP的问题,“Message”是一个类,而不是关联类的实例。我不明白您在回答OP的问题时在回答什么,注意像“我可以有...”这样的问题基本上等待着“是”或“否”的答案...当然需要更多的解释;-) - bruno
显示剩余3条评论

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