本章及后续章节所使用的的MBSE相关的图基本源于《SysML精粹》书上例子。
模块定义图(Block Definition Diagram,BDD)是最常见的一种SysML图。可以在BDD中显示不同类型的模型元素和关系,以说明系统结构的信息。还可以降低修改设计所需要的时间和成本。
在BDD中显示的模型元素——模块、执行者、值类型、约束模块、流说明、接口——都是其他模型元素的类型,它们会出现在其他8种SysML图中。把出现在BDD中的元素叫做定义元素。在实际情况下,定义元素形成了系统模型中其他内容的基础。在BDD中可以显示定义元素之间的结构关系——关联、泛化和依赖。
创建BDD的时机一般发生在执行系统工程活动中,例如:利益相关者需求分析、需求定义、架构设计、性能分析、测试案例开发、集成。
模块定义图的类型缩写是BDD。图的外框代表的模型元素类(modelElementType)可以是:包、模型、模型库、视图、模块、约束模块。图代表的模型元素会作为图中显示的其他元素的命名空间。命名空间只是一种模型元素,可以在其中包含其他模型元素(可以包含其他模型层次结构中的元素)。因此,命名空间是在一种只在系统模型中才有意义的概念,它在系统实例中没有任何意义。很多类型的SysML元素都可以作为命名空间。其中,包是针对出现在BDD中各种定义元素最常见的命名空间。因此,BDD中头部命名的元素通常是在模型层级结构某处创建的包。
定义和实例之间的区别涉及系统设计最基本的概念,并且在SysML中经常出现。某些类型的模型元素(例如:模块、值类型、约束模块)表示对类型的定义;其他类型的模型元素(例如:组成部分属性、值属性、约束属性)代表那些类型的实例。打个比方,房屋的蓝图是对房屋类型的定义;在各个地点根据图纸盖起来的房屋就是那个类型的实例。又比如,在编程语言中,大多存在变量与类定义,以及变量或类实例化。
模块是SysML结构中的基本单元。可以使用模块为系统中或者系统外部环境中任意一种感兴趣的实体类型创建模型。模块代表的是实体的类型,而不是一个实例的类型。
模块的注释是带有元类型<>的矩形,后面是名称分隔框中的名称,如下图所示。必须显示模块的名称分隔框。通常会显示另外的可选分隔框(如组成部分、参考、值、约束、操作、接受、标准端口、流端口、完整端口、代理端口、流属性、结构等),其中会显示模块的特性。特性有两种:结构特性(也叫做属性)和行为特性。
模块可以拥有五种结构特性(也叫做属性):组成部分属性、引用属性、值属性、约束属性、端口。
1)组成部分属性会列在模块的组成部分分隔框中(如下图所示)。组成部分属性代表模块内部的结构,即模块是由组成部分属性构成的。这种关系是一种所属关系。其中SysML明确声明,所属关系意味着一个组成部分属性一次只能属于一个复杂结构。然而,一个组成部分属性可以从复杂结构的一个实例上移除,然后添加到另一个复杂结构的实例上。
在模块的组成部分分隔框中列举一个组成部分属性的时候,会以如下形式展现:“<part name> : <type> [<Multiplicity>]”。其中组成部分名称(part name)由建模者定义,类型(type)一般是在系统模型某处创建的模块的名称。多重性(Multiplicity)是一种约束,限制复杂对象中组成部分属性的实例数量,以单个整数或者一系列整数表示(多重性一般默认为1)。如果你想要一个组成部分属性代表任意数量的实例,那么就可以把多重性设置为0…*,也就是“0或者多个”。或者,可以把多重性设置为*,那是0…*的缩写。
2)引用属性会列举在模块的引用分隔框中(如下图所示)。引用属性代表模块外部的一种结构。和组成部分属性不同,引用属性并不表示所属关系。引用属性可以大概描述为“需要”的关系;带有引用属性的模块因为某种目的需要那个外部结构,或者是为了提供一种服务,或者为了交换事件、能量或者数据。
在模块的引用分隔框中列举一个引用属性的时候,会以如下形式展现:“<reference name> : <type> [<Multiplicity>]”。其中引用名称(reference name)由建模者定义,类型(type)一般是在系统模型某处创建的模块或执行者的名称。多重性(Multiplicity)是引用属性能够表示的实例的数量限制。
3)值属性列举在模块的值分隔框中(如下图所示)。值属性可以代表一个数字(某种类型)、一个布尔值或者一个字符串。当和约束属性结合的时候,值属性会特别有用,那样可以构建系统的数学模型。
在模块的值分隔框中列举一个值属性的时候,会以如下形式展现:“<value name> : <type> [<Multiplicity>] = <default value>”。值的名称(value name)由建模者定义。类型(type)必须是已在系统模型中某处创建的值类型的名称。多重性(Multiplicity)是值属性能够持有的值的数量的限制。默认值(default value)是可选信息,代表它所属模块的实例第一次创建的时候赋予值属性的值。某些值属性会持有赋予的值,其他会持有从系统模型中其他值属性继承(计算)得到的值。为了表示一个值属性是继承得来的、需要在它的名称之前放置一个斜杠(/)。
4)约束属性会列举在模块的约束分隔框中(如下图所示)。约束属性一般代表一种数学关系(一个等式或者不等式),它会使用一系列值属性。在这里所需要的模型精确度要比大多数建模项目所需要的都高。
在模块的约束分隔框中列举一个约束属性的时候,会以如下形式展现:“<constraint name> : <type>”。约束名称(constraint name)由建模者定义。类型(type)必须是已在系统模型某处创建的约束模块的名称。约束模块只是一种特殊的模块——创建它是为了封装可重用的约束表达式。最常见的情况下,约束表达式是一个等式或者不等式。例如,下图显示了一个名为Sufficient Memory的约束模块,其中封装了约束表达式:
也可以在模块的约束分隔框中直接指定约束表达式,但该方式下此约束条件不可复用。
5)端口是代表结构边缘不同交互点的一种属性,通过那些点外部实体可以和那个结构交互——或者是提供服务,或者是请求服务,或者是交换事件、能量和数据。当建模者为模块添加端口的时候,其实就是把一种结构针对它的环境建模为一个黑盒;结构的内部实现会对客户端隐藏。那些客户端只知道结构的接口(它所提供和请求的服务,以及能够流入、流出的事件、能量和数据的类型)。需要特别声明的是,接口会将模块的客户端与所有特定的内部实现解耦(类似于java语言中的interface接口,但端口可以表示更加抽象的层次)。端口可以代表所需要建模的任意类型的交互点。
SysML提供了两种类型的行为特性:操作(operation)和接收(reception)。可以为模块添加操作和接收特性,表达系统或结构的行为。
1)操作表示一种调用后执行的行为,即操作是由调用事件触发的。在BDD 中把操作表示为模块操作分隔框中的字符串:“<operation name> (<parameter list> ) :<return type>[<multiplicity>]”。操作名称(operation name)是由建模者定义的。参数列表(parameter list)是由逗号分隔,拥有零个或多个参数的列表。每种参数的格式都会简短显示。返回值(return type)(如果有)必须是在系统模型中某处创建的值类型或者模块的名称。多重性(multiplicity)会约束操作完成时能够给调用方返回类型的实例的数量。参数列表中的参数代表操作的输入和输出。列表中的每个参数都会以下面的格式显示:“<direction> <parameter name> : <type>[<multiplicity>]=<default value>”。方向(direction)可以是in、out或inout。参数名称(parameter name)是由建模者定义的。类型(type)必须是在模型某处存在的值类型或者模块的名称。多重性(multiplicity)会约束参数能够代表的类型实例的数量。当操作被调用时,如果没有指定一个值作为参数,则赋予参数默认值(default value)。
2)接收代表一种行为,当客户端发送信号来触发的时候,模块就会执行这种行为,即接收是由信号事件触发的。在BDD 中把接收表示为模块接收分隔框中的字符串:“ <<signal>><reception name>(<parameter list> ) ”。关键字<<signal>>必须总是作为接收名称(reception name)的前缀。接收名称必须与模型中触发它的信号名称匹配。只要有必要,你在参数列表(parameter list)中可以显示任意多个参数。列表中的每个参数都会以下面的这样格式显示:“<parameter name> : <type>[<multiplicity>] =<default value>”。参数名称(parameter name)是由建模者定义的。类型(type)必须是在模型某处存在的值类型或者模块的名称。多重性(multiplicity)会约束参数可以代表的类型实例的数量。如果在信号相关属性中没有提供任何值,那么默认值(default value)就是赋予参数的值。
和操作不同,接收无法拥有返回值。接收是异步的;发送信号的客户端不会等待回复。因此,接收的参数只能是输人而不可能是输出。
模块是系统结构化模型的重要部分,而模块之间的关系至少要和它们同等重要。在模块之间可以存在三种主要类型的关系:关联、泛化和依赖。引用属性代表模块外部的结构——模块因为某种目的需要与之连接的结构。引用属性和组成部分属性分别和经常在模块之间创建并在BDD中显示的两类关联相关:引用关联和构成关联。关联只是表示系统中这些结构化关系的另一种标识法。
1)BDD中引用关联的标识法是两个模块之间的实线。如果一端有箭头表示单向的访问,如果两端都没有箭头则表示双向访问(箭头端为被访问端)。关联可以有多种标签。可以选择在线的中间位置显示关联的名称,还可以选择在线的任一端显示角色名称和多重性。关联名称是由建模者定义的字符串,描述能够存在于两个模块的实例之间的关联类型。如下图,引用关联的名称是电力电缆,这个名称描述的是一种关联类型,它可以存在于正确组装的卫星中电子电力子系统和飞行计算机之间。其中,图中下面的BDD显示的是同一模型的等价视图,只是它使用的是引用分隔框标识法,而不是引用关联。
选择使用引用分隔框标识法还是引用关联取决于要在BDD上暴露多少信息。在做决定的时候,另一个需要考虑的因素是在IBD中是否需要为连接器指定类型。如果想要这么做,那么就需要在两个模块之间创建引用关联,并为其命名。在这种情况下,分隔框标识法无法满足需求。
2)两个模块之间的组合关联表示结构上的分解。组合端的模块实例由一些组成部分端模块的实例组合而成。BDD中组合关联的标识法是两个模块之间的实线,在组合端有实心的菱形。在组成部分端有箭头表示从组合端对组成部分的单向访问,如果没有箭头则表示双向访问(组成部分拥有对组合的引用)。如下图所示,这幅BDD表示正确制造和组装的DellSat-77卫星会由一个电子电力子系统、一个高度及轨道控制子系统、一个环境控制子系统以及一个通信和数据处理子系统构成,允许的实例数量由四个组合关联组成部分端的多重性表示。组合端的多重性的上限必须总是1。多重性的下限可以是0或者1。下限为0表示组成部分可以从组合结构中移除;下限为1表示不能移除(在有效的系统实例中,它必须总是依附于组合结构)。
泛化:表示两种元素之间的继承关系 —— 一个更加一般化的元素,叫做超类型,以及一个更具体的元素,叫做子类型。泛化的标识法是一条实线,在超类型的一端带有空心的三角箭头(如下图所示)。泛化是可传递的。泛化表示子类型会继承超类型的所有特性:结构化特性(属性)和行为特性(操作和接收)。除了它继承的特性之外,子类型还可能拥有超类型所不具备的其他特性。因此,建模者通常会称子类型是超类型的一种特殊情况。
依赖是可以在 BDD中显示的第三类关系。依赖意味着:模型中的一种元素,客户端,依赖于模型中的另一种元素,提供者。依赖表示当提供者元素发牛改变时、客户端元素可能也需要改变。依赖在BDD中:标记是带有箭头的虚线,箭头方向从客户端指口提供者。
执行者代表某人或者某件事物,它拥有系统的外部接口。执行者的名称表示人、组织或者其他系统在与你的系统交互时所扮演的角色。SysML为执行者定义了两种标识法:一种是火柴人,一种是在名称前面带有关键字<>的矩形。对于任意类型的执行者——人或者系统——使用任意一种标记法都是合法的。然而,建模者通常会采用火柴人图形标识法来代表人,矩形标识法来代表系统,尽管语言并没有对此做出严格规定。可以在BDD中显示执行者,来说明执行者之间或者执行者和模块之间关联的泛化关系。更常见的是在用例图中显示执行者,表示每个执行者参与了哪种用例。当执行者涉及泛化、引用关联以及组合关联这些关系的时候,所有关于那些关系的关键点也全部适用。但有两条约束;(1)无法在执行者和模块之间定义泛化;(2)执行者不能拥有组成部分;也就是说,它无法出现在组合关联的组合端(一般认为执行者是一个“黑盒”)。
和模块一样,值类型也是一种定义元素———般会定义一种数量类型。在SysML 中有两种值类型——布尔型和字符串型——并不是数量。值类型除可以作为模块的一种结构化特性——类型出现,还可以作为以下情况中的类型出现:模块或者执行者的原子流端口、流规格中的流属性、约束模块中的约束参数、连接器上的条目流(项目流)和条目属性、操作的返回值、操作和接收的参数、活动中的对象节点、固定点和活动参数。通常可以在系统模型中定义三种值类型——原始值类型、结构值类型和枚举值类型。原始值类型没有任何内部结构(它不拥有任何值属性)。它的标识法是名称前带有元类型<<valueType>>的矩形。SysML定义了四种原始值类型:String、Boolean、Integer 和 Real。结构值类型拥有内部结构:一般是两种或多种值属性。枚举值类型(通常叫做枚举)只定义一系列数值(有效的值)。
和模块一样,约束模块也是一种定义元素——它定义了一种布尔型的约束表达式(结果要么是true要么是false的表达式)。最常见的情况下,在约束模块中定义的约束表达式是一个等式或者不等式:用来约束模块的值属性的数学关系。约束表达式中的变量叫做约束参数。约束参数会从它们绑定的值属性那里获得值——也就是被约束的值属性。BDD中约束模块的标识法是名称前面带有元类型<<constraint>>的矩形。约束表达式在约束分隔框中总是会显示在大括号{ }之间。约束表达式中的约束参数会分别列在参数分隔框中。组合关联方法和约束分隔框标识法是等价的:当需要暴露简单约束模块的细节时,就可以使用组合关联;当图的关注点不是那些细节时,可以使用约束分隔框标识法来隐藏它们。
注释是一种模型元素。它包含唯一的属性:一段文字(注释体)。建模者可以在注释体中传递任何需要的信息,还可以选择在图中把注释附加给其他元素,以提供关于它的额外信息。可以在所有九种SysML图中使用注释。注释的标识法通常是一个笔记符号:一个矩形,右上角有折角。可以使用虚线把注释附加给其他元素(。如果需要,可以把注释同时附加给多个模型元素(每个使用一条单独的虚线)。
BDD可以说明在系统内部以及系统外部环境中存在的结构类型。BDD可以说明每种结构提供和需要的服务类型、每种结构必须遵循的约束类型,以及可以存在于运作的系统中的值类型。元素之间的泛化关系可以定义类型的层级关系以及针对抽象设计,提供更高的可扩展性。