当前位置: 首页 > 知识库问答 >
问题:

关联类唯一性

邵展
2023-03-14

我很难理解UML 2.5规范中解释的关联类的概念。最让我困惑的是取自第199页的以下句子:

注意。即使AssociationClass的所有endpoint都具有isUnique=true,也可能有多个实例将endpoint类的同一组实例关联起来。

如本文所述:https://issues.omg.org/issues/UMLR-757这一句话似乎破坏了这一概念的实用性。同时,它使几乎所有解释在UML规范2.5版本之前编写的概念的文本都过时了——例如,请参阅此处的讨论:UML关联类-澄清

但从概念上讲,这实际上是如何工作的呢?假设关联类的所有端都具有isUnique=true,那么当成员端的isUnique属性明确禁止存在此类链接时,如何让一个关联类的多个实例与端类的同一组实例相关联?

我一直认为关联类只是一个带有额外属性和/或操作的常规关联。这种解释现在似乎无效。那么,什么是关联类呢?它如何具有独立于关联成员端的唯一性?似乎有一些潜在某处的多重性(唯一性是不相关的属性,没有高于1的最大多重性),但我不知道在哪里。

共有1个答案

岳承悦
2023-03-14

事实上,这并不是非常清楚,应该得到更好的解释。简而言之:这只是为关联类定义的双重语义学缺乏整合的结果。

根据UML 2.5.1第197页11.5.3.1节:

当关联的一个或多个末端具有isUnique=false时,可以有多个链接关联同一组实例。

我们可以使用逻辑对位来推导:

如果不可能有多个链接关联同一组实例,则关联的所有末端都有isUnique=true。

所以我们希望这也适用于association类,因为association类也是一个关联。

根据UML 2.5.1第11.5.3.2节:

AssociationClass既是一个关联又是一个类,并保留了两者的静态和动态语义。

因此,关联类不仅仅是“具有额外属性的关联”。如果它这么简单,那么关联类完全可以是关联的泛化:专门的关联只会继承额外的属性。但这是明确禁止的第199页:

AssociationClass不能是关联或类的泛化。

因为对类的任何专门化都会失去关联语义,而对关联的任何专门化都会失去类语义。

这种二元性,是我们问题的原因。

根据UML第11.5.3.2节,第199页(我的格式):

AssociationClass的实例具有两个特性,一个是表示作为一种关联的AssociationClass的实例化的链接,另一个是表示作为一种类的AssociationClass的实例化的对象。

如果isUnique=true用于所有关联结束,则保证关联的实例是唯一的。但是请提醒,关联仅与由关联结束组成的元组有关:

关联声明其类型符合或实现关联类型的实例之间可以存在链接。链接是一个元组,关联的每个memberEnd都有一个值,其中每个值都是其类型符合或实现末尾类型的实例。

但是,规范中没有任何内容要求表示关联实例化的类实例化(对象)需要是唯一的。

例如,假设我们在类A和类B之间有一个关联类,并且ab是这些类的实例。假设关联结束有isUnique=true。这意味着只能有一个元组(a, b),因为该关联保证是唯一的。

设P是关联类的一个属性,设(a,b,p1)(a,b,p2)是关联类中类的两个实例。类不知道关联的终点:从类的角度来看,没有单一性要求。从关联的角度来看,我们只有一个元组(a,b),所以它也可以。

该说明只是解释了这种(不幸和模糊的)情况是可能的。

在形式上,没有矛盾。这是关联类定义方式的结果:同时定义类和关联,而不进一步定义各自实例之间的关系。

但这在具有非唯一目的的关联的语义方面产生了一些问题:

当关联的一个或多个端具有isUnique=false时,可能有多个链接关联同一组实例。在这种情况下,链路除了其最终值之外还携带一个额外的标识符。

更准确地说,这使得具有唯一端的关联类毫无用处,因为对于非唯一端可以实现相同的结果:

  • 对于具有非唯一端的简单关联,您可以有重复项,即关联关联端的相同实例的多个链接,这些链接使用附加标识符进行区分。
  • 对于具有唯一结尾的关联类,根据注释,您可以有重复项,即多个对象(类实例)对应于由唯一关联结尾(关联实例)组成的链接。
  • 对于具有非唯一结束的关联类,您可以有重复的,即多个对象实例对应于同一组成员结束。如果您将其解释为关联关联结束的相同实例的多个链接,每个链接与单个对象相关联,或者,如果您将其解释为关联关联结束的唯一实例集的一个链接,则每个链接都关联到多个对象实例,这没有区别。

恕我直言,这是不幸的:

  • 它与我们的心智模型不匹配,在该模型中,具有所有关联endpoint的关联类都具有唯一的=true,对于唯一的组合关联endpoint,该类应该具有该类的唯一对象实例。这显然违背了最不令人惊讶的原则:我从deny开始,花了一段时间才接受这一点,因为它与实现关联类的传统方法有很大的不同
  • 事实上,两种不同的模型,一种具有唯一关联端,另一种没有关联端,可以表达相同的情况

这个问题的一个简单解决方案是要求一个唯一的类实例(对应于关联类的对象)对应于一个唯一关联关联结束的链接。这样,唯一关联结束就意味着唯一的关联对象,而不需要对UML规范进行其他更改。

 类似资料:
  • 使用“关联类型”可以增强代码的可读性,其方式是移动内部类型到一个 trait 作为output(输出)类型。这个 trait 的定义的语法如下: // `A` 和 `B` 在 trait 里面通过`type` 关键字来定义。 // (注意:此处的 `type` 不同于用作别名时的 `type`)。 trait Contains { type A; type B; // 通常

  • 关联类型 定义一个协议时, 有时在协议定义里声明一个或多个关联类型是很有用的. 关联类型给协议中用到的类型一个占位符名称. 直到采纳协议时, 才指定用于该关联类型的实际类型. 关联类型通过associatedtype关键字指定. 关联类型的应用 protocol Container { associatedtype ItemType mutating func append(_ i

  • 问题内容: 我花了点时间弄清楚我需要的SQL查询。 我有一个项目,该项目具有用户的工作室级别的用户角色,并且每个项目都有覆盖/覆盖工作室级别的角色的项目级别的角色。所有角色都是在工作室级别定义的,但是只有一些角色是在项目级别定义的(主要是与相应的工作室级别角色具有不同值的角色) g_studio_UsersInRole g_project_UsersInRole 我需要一个查询,该查询将给定项目I

  • 比如我们有一个用户表,另外有一个个人资料表,他们之间的关联就是一对一的关系。 定义 一对一关联会用到的注解: @OneToOne、@JoinFrom、@JoinTo、@AutoSelect、@AutoInsert、@AutoUpdate、@AutoSave、@AutoDelete 如 imi-demo 中代码所示,定义了一个$ex属性,这个属性关联UserEx模型。 User中id与UserEx中

  • 一对一关联 版本 新增功能 5.1.2 增加selfRelation方法定义当前关联为自关联 关联定义 定义一对一关联,例如,一个用户都有一个个人资料,我们定义User模型如下: <?php namespace app\index\model; use think\Model; class User extends Model { public function profile()

  • 问题内容: 我有以下代码: 当我加入ou时,我得到2个相同单位的ID。这使内部联接tblOrderServiceUnits返回4行,其中2行重复。我需要它只返回不同的2行。如何仅使用不重复到内部联接的不重复ou.id? 不好意思的解释很抱歉,但是基本上我是想看看带有不同子查询的INNER JOIN如何工作,如果有人可以给我一个例子,我可以从那里弄清楚。 问题答案: 例如: