7.7.1 调用操作和发送信号

为了规定通信已经发生,我们使用已发送(‘^’)操作符:

context Subject::hasChanged()
post: observer^update(12, 14)

如果带有参数12和14的update消息已经在该操作的过程中发给observer,那么observer^update(12, 14)产生真。update()要么是observer的类上定义的一个操作,要么是UML模型中定义的一个信号。消息表达式中的实参(本例中的12和14)要符合操作/信息定义的形参。

如果操作/信号的实参未知,或者没有以任何形式被限制,它可以不用指定。这可以使用一个问号来表示。问号之后是一个可选的类型,它有助于在具有同名操作但参数类型不同的情况下找到正确的操作。

context Subject::hasChanged()
post: observer^update(? : Integer, ? : Integer)

这个例子声明update消息已经发给了observer,但参数值未知。

OCL还定义了一个特殊的OclMessage类型。我们可以通过消息操作符:^^来获得实际的OclMessage。

context Subject::hasChanged()
post: observer^^update(12, 14)

这产生已发送的消息序列。集合中的每个元素都是一个OclMessage实例。在该约束的剩余部分中,我们可以使用来自该操作定义的形参名来引用该操作的参数。如果update操作使用了形参 i j 进行了定义,那么我们可以写:

context Subject::hasChanged()
post: let message: Sequence(OclMessage)=observer^^update(?: Integer, ?: Integer) in
    message->notEmpty() and message->exists(m | m.i > 0 and m.j >= m.i)

参数 i 的值未知,但它必须大于0而且参数 j 的值必须大于等于 i。

因为^^操作产生一个OclMessage的实例,消息表达式可以用来指定已发送给不同目标的消息集合。对于一个观察者模式,我们可以写:

context Subject::hasChanged()
post: let message: Sequence(OclMessage)=
                observers->collect(o | o^^update(?: Integer, ?: Integer)) in
        messages->forAll(m | m.i<=m.j)

Messages是一个OclMessage实例的集合,其中每个OclMessage实例都有一个ovserver作为目标。

results matching ""

    No results matching ""