简而言之
确实,这不是很清楚,应该得到更好的解释。简而言之:这只是为关联类定义的双重语义缺乏集成的结果。
详细说明
什么是关联的独特性
根据 UML 2.5.1 第 11.5.3.1 节,第 197 页:
当关联的一个或多个末端具有 isUnique=false 时,可能有多个链接关联同一组实例。
我们可以使用逻辑contraposition推断:
如果不可能有多个链接关联同一组实例,则关联的所有端点都具有 isUnique=true。
所以我们希望这也适用于关联类,因为关联类也是一个关联。
关联类同时是两个不同的东西
根据 UML 2.5.1 第 11.5.3.2 节:
AssociationClass 既是关联又是类,并且保留两者的静态和动态语义。
因此,关联类不仅仅是“具有额外属性的关联”。如果就这么简单,那么关联类可以完美地成为关联的泛化:专门的关联只会继承额外的属性。但这在第 199 页被明确禁止:
AssociationClass 不能是 Association 的概括或
类。
因为任何对类的特化都会失去关联语义,而对关联的任何特化都会失去类语义。
而这种二元性,就是我们问题的根源。
这种二元性对实例的影响
根据 UML 第 11.5.3.2 节,第 199 页(我的格式):
AssociationClass 的实例具有将 AssociationClass 的实例化表示为一种关联的链接和 表示实例化的对象的特征> AssociationClass 作为一种类。
如果所有关联结束的isUnique=true,则保证关联的实例是唯一的。但请注意,关联仅与由关联端组成的元组有关:
关联声明其类型符合或实现相关类型的实例之间可以存在链接。链接是一个元组,对于 Association 的每个 memberEnd 都有一个值,其中每个值都是一个实例,其类型符合或实现末尾的类型。
但是,规范中没有任何内容要求表示关联实例化的类实例化(对象)必须是唯一的。
例如,假设我们在类A 和类B 之间有一个关联类,而a 和b 是这些类的实例。假设关联结束有isUnique=true。这意味着只能有一个元组(a,b),因为保证关联是唯一的。
设P为关联类的一个属性,设(a,b,p1)和(a,b,p2)为关联类中类的两个实例。类不知道关联端:从类的角度来看,没有唯一性要求。而且从关联的角度来看,我们只有一个元组 (a,b) ,所以也没关系。
注释只是解释了这种(不幸和模棱两可的)情况是可能的。
是否存在矛盾或不一致?
形式上,没有矛盾。这是关联类定义方式的结果:同时一个类和一个关联,没有进一步定义各个实例之间的关系。
但这会在具有非唯一端的关联的语义方面产生一些问题:
当关联的一个或多个端点具有isUnique=false 时,可能有多个链接关联同一组实例。在这种情况下,链接除了它们的最终值之外还带有一个额外的标识符。
更准确地说,这使得具有唯一端的关联类无用,因为使用非唯一端也可以实现相同的结果:
- 对于具有非唯一端的简单关联,您可以有重复项,即多个链接将关联端的相同实例关联起来,这些实例通过附加标识符进行区分。
- 对于具有唯一端的关联类,根据注释,您可以有重复项,即多个对象(类实例)对应于由唯一关联端(关联实例)组成的链接。
- 对于具有非唯一端的关联类,您可能有重复项,即多个对象实例对应于同一组成员端。如果您将此解释为与关联端的相同实例相关联的多个链接,每个链接与单个对象相关联,或者,如果您将此解释为与关联端的一组唯一实例相关联的一个链接,则没有区别,那将是每个都与多个对象实例相关联。
恕我直言,这很不幸:
- 它与我们的心智模型不匹配,在这种模型中,所有关联端都具有
isUnique=true 的关联类应该具有该类的唯一对象实例以用于唯一组合关联端。这显然违背了最小惊讶原则:我从否认开始,但我花了一段时间才接受这一点,因为它与实现关联类的传统方式截然不同。
- 两种不同的模型,一种具有唯一的关联端,另一种没有,实际上可以表达相同的情况。
这个问题的一个简单解决方案是要求一个唯一的类实例(对应于关联类的对象)来对应一个唯一关联关联端的链接。这样,唯一的关联端就意味着唯一的关联对象,而不需要对 UML 规范进行其他更改。