我想使用OCL链接两个表示两个抽象级别的相同模型的类图。
为了说明,请考虑一个抽象模型A,它包含一个与其自身具有“父”关联的Person。还有一个更具体的模型B,有男性和女性,男性和女性继承人,两个协会,一个人与男性之间的“父亲”,一个人与女性之间的“母亲”。
我想使用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()
答案 0 :(得分: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}
但是,如果您将包Abstract
合并到包Concrete
中,那么Concrete::Person
会从parents
带来Abstract::Person
,而您不希望这样。{ / p>
我特别想分开模特。我们的想法是具体模型不必明确地带有抽象。
请注意,实例不限于单个超类型,然后您可以指定每个Concrete::Person
为Abstract::Person
,并且每个Abstract::Person
都是Concrete::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
中的关联(它们是不同的类型,即使两者都适用于相同的实例)。
此外,Concrete::Person
上的第一个不变量实际上是多余的,因为如果自身不符合oclAsType
,invalid
将返回Abstract::Person
。
答案 1 :(得分:0)
(RSS表明这是一个新话题!)
问题在于,抽象/具体变体在某种意义上是不同的类,但在另一种意义上是相同的类。因此,您必须根据消费者是否希望将抽象/具体视为不同/相同的类来划分您的消费者,并为每个消费者定义“相同”的含义。
对于人类,您可以使用拼写约定使不同的类“相同”。或者注释或无数的UML关联。
如果你想要某种程度的功能相同性允许在某些模拟中交替使用“抽象”/“具体”类,你可能需要“抽象”和具体类来从一个共享接口继承,你有一个独特的'抽象'/'具体'实现。
如果相同用于文档目的,您可以考虑将一个转换为另一个的模型转换语言。许多M2M实际上只是OCL的外语,为模型导入/导出和变异提供支持。 M2M可以捕获与“抽象”和“具体”相关的常规习语,并且可能适合于数学证明和/或自动代码生成。它当然应该满足追踪必需品的要求。