第一步:
这里发现UML2.5.1中的一处错误:
图四、Figure9.10中的一处错误。
错误就在于最下面一个关联右端点处的标记redefines,有了这个标记,就应该意味着此关联特化了某个关联,但是如果我们用“A_ownedAttribute_class”搜索本文档,就会得到如下内容:
11.9.12 A_ownedAttribute_class [Association]
11.9.12.1 Diagrams
Classes, Properties
11.9.12.2 Member Ends
· Class::ownedAttribute
· Property::class
可以看到,其中并无任何其特化其它关联的信息。
因此可以断定,此处的redefines应该是一处错误,正确的内容应该是:
subsets ownedMember。
第二步:
经过进一步的排查,发现这里不是错误,而是本规范遗漏了一个关联泛化关系(在类图中这个关联泛化关系仍旧存在,只是在上面的文字(11.9.12)中被遗漏了),即关联 A_ownedAttribute_class应该是关联A_ownedAttribute_structuredClassifier的特化。这两个关联的一端都是Property(此端角色名都是ownedAttribute),另一端则分别为Class和StructuredClassifier,它们在这一端的角色名分别为class和structuredClassifier。
通过这个错误的排查,我们可以发现这样一个现象:同一关联两端的标记如果有多个,则一端的标记和另一端的标记不一定具有一致的前后关系。就以图四为例,如果最下面的关联(Class和Property之间的关联)两端的标记的前后关系一致,则分别应该是:
{subsets namespace, subsets structuredClassifier, subsets classifier}
{ordered, subsets attribute, redefines ownedAttribute, subsets ownedMember}
而不应该是现存的:
{subsets namespace, subsets structuredClassifier, subsets classifier}
{ordered, subsets attribute, subsets ownedMember, redefines ownedAttribute}
这样做可行的原因就在于关联两端的角色名的命名规则可以保证不会发生匹配错误的情况,即使关联两端的标记的前后关系不一致。
第三步:
经过进一步的排查,发现这也不是遗漏。
通过观察,可以发现,如果两个关联之间存在泛化关系,则必须满足关联的一端由关联拥有。如果继承和被继承的关联中至少有一个关联的两端都由关联两端的类拥有,则由于这两个关联中至少有一个在语法上已经不再存在,因此就无法定义这两个关联之间的泛化关系。
关联两端都由关联拥有是没有任何意义的,因为此时此关联对于关联两端的类而言没有任何用途。
再举一个更奇葩的例子:
下图是Figure10.7的一个片段:
图五、Figure10.7的一个片段
在图五中可以看到,BehavioredClassifier与InterfaceRealization之间的二元关联(记为Asso6)中,左侧的标记为两个,而右侧的标记为一个;
InterfaceRealization和Interface之间的二元关联中(记为Asso7)中,上侧的标记为一个,下侧的标记则为两个。
经过阅读原文中的文字说明,发现这是本文的一个错误:简单来说,其就是将Asso6右侧的标记与Asso7下侧的标记搞反了。只要将这两处标记对调即可。
通过这个例子,也给我们一个提示:如果某个类图有匪夷所思的内容,则可以结合相关的“Classifier Descriptions”和“Association Descriptions”中的内容进行复核,如果两者确实一致,则是我们的理解有问题;如果两者不一致,则是原文中的错误。
下一篇文章将讨论redefines的实现效果,对于这个问题本人有一个解释,但是不能确定这个解释是否正确,因此还欢迎大家踊跃讨论。
参考文献:
UML2.5.1