1

我想使用 OCL 来链接两个在两个抽象级别上表示相同模型的类图。

为了说明这一点,考虑一个抽象模型 A,它包含一个类 Person,该类与其自身具有“父母”关联。还有一个更具体的模型 B,它具有 Person、Male 和 Female 类,其中 Male 和 Female 继承自 Person,以及两个关联,Person 和 Male 之间有一个“父亲”,Person 和女性之间有一个“Mother”。

我想使用 OCL 将两个模型链接在一起。也就是说,我想说具体模型中的“母亲”和“父亲”代表了抽象模型中的“父母”关联。

我知道可以将所有关联放在一个模型中,然后说类似

context Person inv:
 self.mother->forAll(m | m in self.parents) and
 self.father->forAll(f | f in self.parents) and
 self.parents->forAll(p | p in self.mother or p in self.mother)

但我特别想分离模型。这个想法是具体模型不必明确地携带抽象。

我曾考虑使用包将每个模型放在单独的命名空间中,但据我所知,我最终得到了两个不同的 Person 类,每个包中都有一个。

有没有办法可以说不同包中的两个类名代表同一个类?那是同一组对象吗?例如,下面的表达式会实现这一点还是永远是假的?

Abstract::Person.allInstances() = Concrete::Person.allInstances()
4

2 回答 2

1

我曾考虑使用包将每个模型放在单独的命名空间中,但据我所知,我最终得到了两个不同的 Person 类,每个包中都有一个。

正确的。除非您定义从Abstract包到包的包合并Concrete

包合并在 UML 的 12.2.3 节中定义:

此功能旨在在不同包中定义的元素具有相同名称并旨在表示相同概念时使用(...)因此,对包含在接收包中的模型元素的任何引用都意味着对结果的引用合并而不是包含在该包中的增量。[UML 2.5]

package Abstract
context Person 
inv: not self->closure(parent)->contains(self)

package Concrete -- merges from package Abstract
context Person
inv: parents->asSet() = Set {mother, father}

但是如果你将 package 合并Abstract到 packageConcrete中,那么Concrete::Person会带来parentsfrom Abstract::Person,而你不希望这样。

我特别想分离模型。这个想法是具体模型不必明确地携带抽象。

请注意,实例不限于单个超类型,然后您可以指定 everyConcrete::Person是 an Abstract::Person,并且 everyAbstract::Person是 aConcrete::Person

package Abstract 
context Person inv: self->oclIsKindOf(Concrete::Person)

package Concrete
context Person 
inv: self->oclIsKindOf(Abstract::Person) 
inv: self->oclAsType(Abstract::Person).parents->asSet() = Set {mother, father}

强制转换是必需的,因为Concrete::Person不知道其中的关联Abstract::Person(它们是不同的类型,即使两者都适用于相同的实例)。

此外,第一个不变量 onConcrete::Person实际上是多余的,因为如果 self 不符合oclAsType将返回。invalidAbstract::Person

于 2016-08-29T11:56:42.130 回答
0

(RSS 表明这是一个新话题!)

问题是您的抽象/具体变体在某种意义上是不同的类,但在另一种意义上是相同的类。因此,您必须根据消费者是否希望将抽象/具体视为不同/相同的类来划分消费者,并为每个消费者定义“相同”的含义。

对于人类,您可以使用拼写约定使不同的类“相同”。或注释或无数的 UML 关联。

如果您想要某种程度的功能相同性,允许在某些模拟中互换使用“抽象”/“具体”类,您可能需要“抽象”和具体类都从您具有不同“抽象”的共享接口继承/ “具体”的实现。

如果出于文档目的相同,您可以考虑使用一种模型转换语言,将一种语言转换为另一种语言。许多 M2M 实际上只是 OCL 的一种外部语言,为模型导入/导出和变异提供支持。M2M 可以捕获与“抽象”和“具体”相关的常规习语,并且可能适用于数学证明和/或自动代码生成。它当然应该满足需求跟踪的必要性。

于 2017-12-09T09:15:29.603 回答