智睿思维Logo智睿思维

MBSE建模学习之五:交互和序列图

交互(Interaction)

交互(Interaction)是一种具体的行为元素,它用对象之间消息传递的方式说明行为发生过程的顺序和互相传递的信息。对交互进行说明的图主要是序列图(Sequence Diagram, 在UML标准中还有使用时间图、通讯图或交互概览图对其进行说明,SysML标准只使用序列图)。

作为一种行为,交互也是具有行为的基本特征:具有输入参数、返回参数;它可以作为一个模块(Block)或其它行为类目(BehavioredClassifier)的拥有行为(OwnedBehavior);它可以作为一个操作(Operation)、接收(Reception)的“方法”(Method)。

和活动(Activity)一样,交互同时也是一个模块(Block)。一个复杂的交互行为可以进行分解。在上层的交互行为中,通过一个“交互使用”(InteractonUse)元素表示对下层或其它交互的调用。

作为行为,交互的发生一样需要规定发生的语境(Context)。如果交互是某个模块的拥有行为,则这个模块是交互行为的语境;否则它自己是它的语境。说明交互的序列图中的元素都是它的语境范围内的元素。下面介绍序列图中的生命线、消息等元素的时候,总是要涉及到代表交互的语境的模块。

下面先看一个代表交互的序列图,然后说明图中元素的作用和意义。在这个图中,上面的“汽车域”(域是扩展的“模块”类型,代表特殊的模块)是下面“启动车辆黑盒”交互的语境(Contex),因为“启动车辆黑盒”交互是它的一个拥有行为。

生命线(Lifeline)

生命线元素代表模块中的一个部件(或其它属性)的实例,这个模块是生命线所在的序列图代表的交互元素所属的模块。在上面这个图中,“HSUV: HybridSUV”是“启动车辆黑盒”交互所属的“汽车域”模块的一个部件属性;“driver: 司机”是“汽车域”的一个执行者属性。

生命线用一个下面有一条虚线的矩形框表示,矩形框称作它的“头”。这个虚线代表了生命线代表部件属性中发生事件的顺序,它总是从上到下的顺序。

生命线的“头”中显示的文本的语法说明如下:

<lifelineident> ::= ([<connectable-element-name>[‘[‘ <selector> ‘]’]] [: <connectable-element-type>][<decomposition>]) |‘self’

中文化的语法:([<名称>[‘[‘ <选择器> ‘]’]] [: <类型 >][<分解>]) |‘自己’

一般情况下,生命线像一个属性一样,显示代表的属性的名称和类型,如“driver: 司机”,“driver”是代表属性的名称,“司机”是代表元素的类型。

“<选择器>”是可选的部分,当属性表示多个实例的时候,选择器表示其中具体那个实例。如果没有选择器,表示可以是任何一个实例。例如对一个飞机的驾驶员属性,可以用“pilot[主]:飞行员”表示飞机的主驾驶员。

可选的“<分解>”语法部分,表示这个生命线上发生的行为,可以在一个更具体的交互元素表示的序列图中显示。这个交互元素代表的行为属于生命线的类型表示的模块。在这个分解的交互元素的序列图中,当前生命线类型元素将分解为它的组成部分代表的子生命线。用关键字 “引用”(或ref)+“交互元素名称”表示。“strict”说明“分解交互元素”序列图中的子生命线的都是“严格”顺序。(有关分解的详细说明,参见UML2.5标准)。

特殊情况下,生命线也可以直接表示交互所属的那个模块,而不是模块中的属性。这时候,用一个特殊的关键字“self”(MBSES软件中可以用中文“自己”)表示。

消息(Message)

消息代表生命线之间的通信,从发送消息的生命线指向接收消息的生命线。消息可以直接连接到生命线上,或者连接到生命线上的执行说明。

消息的发送和接收伴随着生命线上行为事件的发生,在消息发送端表示发送事件的发生;接收端表示接收事件的发生。所以在消息的两端会自动生成“消息发生说明”(MessageOccurrenceSpecification)元素。当消息的一端是连在序列图的外框,或者“组合片段”(CombinedFragment)的边框的时候,这个消息端上表示一个“门”(Gate),“门”表示交互元素或组合片段和外界的接口。

消息的“签名”(signature)属性是消息调用的操作(Operation,接收生命线的类型元素具有的操作),或者一个信号(Signale)。如果消息的通信类型是同步调用或异步调用,则签名应该是接收生命线的一个操作;如果通信种类是异步信号,则签名应该是模型中定义的一个信号元素。同时,作为接收的生命线的类型元素,也应该有一个对应的“接收”(Reception)。

在表示消息的连线上,会显示说明消息的文本标签。通用消息的语法表示为:

<message-label> ::= <request-message-label> | <reply-message-label> | ‘*’

它表示消息表示为“请求消息标签”或“回复消息标签”或一个“*”。“*”表示任何类型的消息。“请求消息标签”或“回复消息标签”的具体语法根据消息的类型确定。

“请求消息标签”(除了回复消息以外其它各种消息)语法如下:

<request-message-label> ::= <message-name> [‘(‘[<input-argument-list>] ’)’]

中文的解释:<消息名称>([<输入参数列表>])

如果消息有一个“签名”属性,则消息的名称一定和“签名”属性对应的操作或信号的名称相同。否则没有限制。

可选的“输入参数列表”是对应调用“签名”的操作时输入的参数,或者对应“签名”信号的属性(或者说对应“接收”的输入参数,因为“信号”和“接收”是对应的)。每个输入参数的语法是:

<input-argument> ::= [<in-parameter-name> ‘=’] <value-specification> | ‘-’

意义:[输入参数名称=]<值>|’-‘。输入参数名称是可选的,都显示或都不显示。“-”表示一个通配符,只是表示对应一个参数,但没有指定任何值。

例如一个用户登录身份验证的消息表示为:

“login(userName=‘admin’,password= ‘1234567’)”

“login”对应系统的一个登录的操作,使用’admin’用户名及默认的’1234567’作为默认密码进行系统的登录。

如果是表示一般用户的登录,则传递的消息为:

“login(userName, password)”

这个消息表示使用用户生命线代表实例的’userName’属性值和’password’属性值作为参数进行登录。

“回复消息标签”的语法为:

<reply-message-label> ::= [<assignment-target> ‘=’] <message-name>[‘(’ [<output-argument-list>] ‘)’] [‘:’ <value-specification>]

中文:[<赋值目标]=<消息名称>([输出参数列表]):<返回值>

“回复消息”是操作执行完,返回给调用生命线的数据。可选的“赋值目标”表示返回值赋值为调用生命线的某个属性。完整的例子如下:

“area=returnArea(w=width:16):96”

这个返回消息表示返回值“96”赋给了调用生命线的“arean”属性,同时,“w”作为输出参数“width”对应的变量,赋值为16。这条消息通过输出参数及返回参数,返回了两个值。

消息的分类,从两个维度进行分类。一个是按两端的事件,有以下四类(MessageKind):

“完整”:有发送事件和接收事件。

“丢失”:有发送事件、无接收事件。它表示接收事件的对象超出了模型的范围,无法描述或无需描述。

“发现”:无发送事件、有接收事件。它表示发送事件的对象超出了模型的范围,无法描述或无需描述。

“未知”:无发送事件、也无接收事件。这种消息在最终的模型中不应该出现,只是作为临时的数据出现。

消息按调用及返回的方式(MessageSort),有以下几类:

“同步调用”:消息是一个调用操作的消息,而且是同步调用。“同步”的意思,是当调用的时候,调用过程会停下来,等待被调用操作返回消息才继续下面的动作。例如一个“登录”消息,调用“登录”操作,必须等待登录结果才继续下面的操作。

“异步调用”:消息是一个调用操作的消息,而且是异步调用。“异步”的意思,是当调用的时候,调用过程不停下来,继续执行下面的动作。

“异步信号”:凡是消息签名是“信号”,则消息就是“异步信号”。因为信号的发送,总认为是异步的。无论接收信号方是否处理信号完毕,都不影响发送方继续其它工作。

“创建消息”:表示创建一个“生命线”的实例。创建消息指向被创建生命线的“头”。

“删除消息”:表示终止另一条生命线的消息。删除消息总是指向生命线的末端,而且末端有一个“X”形的“删除发生说明”事件。

“回复”:表示调用操作之后,操作回复给调用方的消息。

各种消息的线及两端的表示符号都不同。详细情况可以参见“智睿思维基于模型的系统工程软件”中消息的表示方法,通过选择消息的不同类型,消息的表示方法会变化。

执行说明(ExecutionSpecification)

执行说明表示生命线上一个行为(Behavior)或动作(Action)的执行。执行说明显示为一个覆盖生命线的一部分的一个细窄的矩形框。在矩形框的上下两端分别表示行为或动作的开始和结束事件(用两个执行发生说明(ExecutionOccurenceSpecification)元素定义)

在UML中,执行说明是一个抽象类。具体的执行说明有两种:

行为执行说明(BehaviorExecutionSpecification):它表示一个行为的执行。这个行为是执行说明覆盖生命线的类型的一个行为。

动作执行说明(ActionExecutionSpecification):它表示一个基本动作(Action)的执行。这个动作是执行说明覆盖的生命线的类型的行为中的一个动作。

交互使用(InteractionUse)

交互使用表示对另一个交互的引用。通过交互使用,可以对交互行为进行分解。

交互使用通过一个左上角有一个“引用”(ref)标签的方框表示,框中可以简单仅仅显示引用的下级交互的名称;也可以显示被引用交互的完整表达式。

组合片段(CombinedFragment)

除了上述序列图中的常用元素,对于复杂的行为过程,包括循环、并行、可选等,可以通过一个“组合片段”(CombinedFragment)来表示。

组合片段有多种操作类型。其中常用的如下:

可选(opt):代表一系列可选的事件,如果条件(称为守卫)成立,那么就会在交互的执行过程中发生。相当于程序语言中的“if”条件语句

备选(alt):代表两个或多个可替换的系列事件,他们会在交互的一次执行中发生。其中只能有一个条件为真的事件发生。相当于编程语言的“if..else if..else..”语句。

循环(loop):代表一系列事件,只要条件成立,可以在交互的一次执行过程中发生多次。

并行(par):代表两个或多个系列的事件,他们会在交互的执行过程中并行进行。

其它操作符,请参考MBSES软件的在线手册。(请关注“智睿思维MBSE”公众号,可以随时查看在线帮助手册)

状态不变量(StateInvariant)

包含一个约束条件,这个约束条件是对生命线的属性、当前范围的变量,或者一个状态的值进行约束。在约束条件满足的时候,继续下面的过程。

状态不变量有两种表示方式。一种是包含约束表达式的一个文本框(如下面的序列图案例中所示);另一种是像一个状态机图中的状态一样的表示方式,中间是一个状态的名称。这个状态对应生命线的一个状态(这个状态应该也有一个“状态不变量”的约束属性,表示当对象处于这个状态时,某个属性保持不变,所以这个约束才称为“状态不变量”,例如“{状态==工作}”表示工作状态的约束)。

序列图案例

我们还是看一个应用了组合片段的序列图案例。这个案例是我们在“MBSE建模学习之四:活动(Activity)及活动图”中所举案例“执行霍曼转移”活动的序列图表示方式。霍曼转移的原理见这篇文章。序列图如下(来自《SysML精粹》图7.1):

这个图代表的交互元素是“执行霍曼转移,主成功场景”,它的语境(Context)是“DellSat-77卫星”模块。这个序列图中,有三个生命线。“ps :推进子系统”和“mans :微型自主导航系统”是“DellSat-77卫星”的直接部件属性,而“fc:飞控计算机”是它的部件“通讯和数据处理子系统”的部件属性。

在这个图最外层是一个“并行”的组合片段,分成上下两个并行执行的过程(在活动图中,对应一个分支节点,分出来两个并行的流程)。

在上面的操作域中,又是一个“循环”组合片段,这个循环的组合片段中,不断的根据当前高度计算新的轨道半径,并把包含“当前轨道半径”参数的消息发送回“fc:飞控计算机”。

在下面的操作域中是一个“可选”组合片段。这个“可选”组合片段的守卫条件是“命令是否合法=true”,表示只有当到达的命令判断是合法的情况下,这个组合片段中的过程才会执行。在执行时,按从上到下顺序,首先是发回一个“响应发送(响应)”的异步消息。然后,当系统时间到达“当前命令.执行时间”约束规定的时间的时候,“fc:飞控计算机”向“ps:推进子系统”发送同步消息“点火推进器()”,使推进子系统点火。“ps:推进子系统”执行“点火”的执行说明有一个时间范围约束,规定点火的持续时间(从开始到结束)应满足“2~5分钟”。这时候卫星经过加速后进入一个椭圆的轨道。此时,最外层并行组合片段的上半部分过程一直在重新计算和更新当前轨道半径。当这个轨道半径符合状态不变量规定的条件“{当前轨道半径==当前命令.要求轨道半径}”时,“fc:飞控计算机”向“ps:推进子系统”发送第二次点火消息,卫星再次加速,进入预定的圆形轨道。