模块可以用来为系统中任何级别的产品建立模型。在SysML标准中,模块元素是扩展了UML的类(Class)元素的一个构造型。作为系统中最常见的一种类型元素,模块的构造型标识«模块»(«block»)可以不显示。或者按照标准原文的说法,如果没有构造型就表示元素是一个模块。模块可以代表任何类型的对象。上至整个系统,下至系统中一个最小的单元。可以是一个物理模块,也可以是一个逻辑模块。
模块的标识是一个方框,包括构造型、模块名称,以及表示模块属性或方法的各种分区。模块的各种属性、操作、关系可以显示在模块节点中的一个方框内,这些方框称为模块节点的一个“分区”(Compartment)。除了模块名称必须显示之外,模块其它的任何部分都可以选择显示或不显示。默认情况下,只要分区中有数据就会显示。如果需要控制是否显示某个分区,可以通过属性框中的属性来设置是否显示。而没有数据的分区一定是不显示。
如下图所示一个模块典型表示方法,以及模块的属性框中是否显示的控制选项。
在MBSES软件中,模块的视图总共有26种标准的分区。用户也可以添加自定义的用户分区。模块的26种标准分区列表如下:
序号 |
种类 |
分区名称 |
|
1. |
结构特征 |
部件(parts) |
类型是“模块”且聚合关系是“组合”的属性 |
2. |
结构特征 |
引用(references) |
类型是“模块”且聚合关系不是“组合”的属性 |
3. |
结构特征 |
值(values) |
类型是值类型(ValueType)的属性 |
4. |
结构特征 |
约束(constraints) |
类型是“约束属性”的属性 |
5. |
结构特征 |
连接器(connector properties) |
类型是关联的属性 |
6. |
结构特征 |
参与属性 (participant properties) |
关联模块中,和两端被关联的模块对应的属性 |
7. |
结构特征 |
属性(properties) |
任何类型的属性 |
8. |
行为特征 |
操作(operations) |
类型为操作的行为特征 |
9. |
行为特征 |
接收(receptions) |
类型为接收的行为特征 |
10. |
行为 |
类目行为(classifier behavior) |
表示模块开始工作,一直到结束的整个过程的行为。一个模块只有一个类目行为,一般是一个状态机。 |
11. |
行为 |
拥有行为(owned behaviors) |
模块能够提供的各种服务。拥有行为包括类目行为,但是在MBSES中拥有行为分区中不重复显示类目行为。 |
12. |
结构特征 |
绑定引用(bound references) |
类型是绑定引用的属性 |
13. |
构造型 |
构造型 (stereotypes) |
当构造型在分区中显示的时候,显示应用的构造型的属性 |
14. |
端口 |
端口(ports) |
类型是端口的属性 |
15. |
端口 |
完整端口(full ports) |
类型是完整端口的属性 |
16. |
端口 |
代理端口(proxy ports) |
类型是代理端口的属性 |
17. |
属性 |
流属性(flow properies) |
类型是流属性的属性 |
18. |
分配关系 |
分配从(allocatedFrom) |
分配关系的源端元素 |
19. |
分配到(allocatedTo) |
分配关系的目标端元素 |
|
20. |
需求关系 |
改善(refines) |
改善的需求 |
21. |
满足(satisfies) |
满足的需求 |
|
22. |
跟踪从(tracedFrom) |
跟踪的需求 |
|
23. |
验证(verifies) |
验证的需求 |
|
24. |
结构 |
结构(structure)分区 |
结构分区显示一个局部的内部模块图,显示模块的结构 |
25. |
命名空间 |
命名(namespace)空间分区 |
命名空间分区显示一个局部的包图,命名空间分区中的模块是当前模块嵌套类而已 |
26. |
图形 |
图形(image)分区 |
显示一个代表模块图形 |
这26种分区,简单的说明和用途如下:
(1)部件(parts):
部件分区中属性的类型也都是模块,它表示父级模块的组成部分。每个部件的工作过程在父级模块开始之后才能开始。而在父级模块工作结束后,所有部件属性都不可能再工作。一个部件只能属于某一个模块,它表示模块的内部结构。
(2)引用(references)
引用属性的类型也是一个模块,不过这个子模块不是当前这个模块内部的模块。它可能位于另一个模块内部,但是当前这个模块的工作需要这个外部部件提供功能,或者向这个外部模块提供数据或信息。
(3)值(vallues)
在这个分区下面显示值属性。
值属性的类型是一个值类型(ValueTtype)。SysML的值类型在继承UML数据类型的基础上,增加了“单位”、“数量类型”这些具有更确定工程意义特性的数据类型。例如,一个产品的“重量”、“高度”等等这些物理属性。没有单位的数据类型作为属性类型的属性也是值属性,例如仅仅表示数量的属性(单位其实是“个”)、仅仅是“是”或“否”这样的布尔值、或者一个字符串。
(4)约束(constraints)
约束分区中的约束一般是一个数学表达式,它表示模块各属性参数之间的数学关系。SysML扩展了约束的应用,约束分区中的“约束”也可以是一个“约束属性”。约束属性的类型是一个约束模块,约束模块中包含了可以重复使用的约束关系。也就是通过“约束属性”,把通用的数学关系放到约束模块中。进一步描述约束模块中数学关系和模块的参数之间的关系,可以用一个参数图表示。
(5)连接器属性(connectorProperties)
连接器(Connector)是对应各部件之间关联关系的属性。连接器的类型是一个关联(Associattion)或关联模块(AssociationBlock)。连接器可能只是表示内部模块之间数据或信息的传送,也可以是具体的有实物的连接器产品,如电连接器、机械连接器等。
(6)参与属性(participantProperties)
当连接器的类型是一个关联模块的时候,连接器两端连接的部件,对于连接器的类型:关联模块来说是“参与属性”。下图说明了一个关联模块中“参数属性”的例子。
(7)属性(properties)
这个普通属性的分区可以显示任何类型的属性,也就是属性的类型可以是任何类型,甚至可以为空。
(8)操作(operations)
操作表示模块可提供的一个服务。对于软件模块,对应这个类提供的方法、过程或一个函数。对于硬件模块,它表示模块可提供的方法接口,可接收参数并完成一个功能。但是UML\SysML中操作只是一个方法接口,它的实现需要通过对应方法的行为图来描述。
(9)接收(receptions)
接收表示模块接收信号并进行处理的一个方法。接收一定对应在模型中某个地方定义的信号(Signal),它的参数和信号的属性对应。接收的调用一定是异步的,也就是一个模块向另一个模块发送信号,是不等待返回消息就继续其它工作或发送下一个信号。(同步的概念是调用另外一个模块的操作的时候,会等待返回的消息,收到返回消息才继续下面的工作)
(10)类目行为(classifier behavior)
一方面,行为表示模块可提供的一种服务,输入什么、输出什么。另外,行为有对应的行为图(活动图、序列图、状态机图)。在行为图中详细说明了模块是怎么处理输入信息(输入参数)并加工、转化为输出信息(输出参数)的。这里的“信息”表示任何物质,不止是数据。也可以没有输入、输出信息,只是表示模块的活动过程。
模块的类目行为就是表示模块从开始到结束的活动过程。一个模块只能有一个类目行为。例如用一个状态机表示设备的活动过程。这个状态机有启动、开机、待机、关机、停机等各种状态。
(11)拥有行为(owned behaviors)
一个模块拥有的所有行为。一个模块可能提供多种服务或功能,每个可以对应一个行为。
(12)绑定引用(bound references)
绑定引用是一个引用属性,同时这个引用属性通过绑定连接器绑定到内部的一个部件。“绑定”的概念是两个值始终相等,或者是同一个对象的意思。通过绑定关系,同一个对象在两个地方使用。例如计算机中映射了另外一个计算机的一个存储空间作为本地盘符。
(13)构造型(stereotypes)
构造型是一种扩展标准元素功能的机制。例如定义一个表示元素作者、版本的构造型。模块构造型的属性可以显示在分区中,也可以显示在头部。通过模块属性框中节点显示属性设置。构造型属性是在设计模型时输入的,而模块的属性是在模块实例化的时候才赋值的,这个也是区分构造型属性和模块自己属性的一个方法。
(14)端口(ports)
端口是一个特殊的部件,它是专门用来和外界交换信息的。例如一个计算机的USB端口、提供显示信号的HDMI端口。
端口一般表示为模块边框上的小方块。也可以显示在分区中。可以通过属性框中模块节点的显示属性设置。
(15)完整端口(full ports)
完整端口是我们把它当作一个独立的部件来看待的,这个部件也是一个可能具有各种属性、功能行为的一个模块。可以说完整端口是自己直接处理输入的信息、输出处理后的信息(当然处理过程也是可以调用其它内部模块的功能的)。
(16)代理端口(proxyPorts)
代理端口的类型一定是一个接口模块。代理端口通过一个绑定连接器绑定到一个内部的模块。可以说代理端口自己并没有处理信息的功能,处理信息的其实是另外一个内部模块。
(17)流属性(flowProperties)
流属性是具有方向的属性。流属性的方向有“进”“出”或“进出”(in, out, inout)。流属性的类型可以是值类型、模块或信号。
(18)分配从(allocatedFrom)
“分配”是SysML中定义的一个表示两个元素之间特殊关系的元素。例如可以为结构分配行为、为物理结构分配逻辑结构,为结构分配资源。
“分配从”表示一个元素被分配到了这个模块。例如一个一个活动被分配到这个模块。
(19)分配到(allocatedTo)
“分配到”表示这个模块分配到了另外一个元素。例如一个逻辑模块分配到一个物理模块。
(20)改善(refines)
“改善”是表示模块和需求之间的关系,意思是这个模块的说明更详细的说明了需求。
(21)满足(satisfies)
“满足”表示模块满足了某个需求。
(22)跟踪从(tracedFrom)
“跟踪从”表示这个模块跟踪回某个需求。通过跟踪关系可以知道模块设计和需求之间关系。
(23)验证(verifies)
“验证”表示模块验证了某个需求。作为验证关系的模块,一般是一个“测试案例”元素。
(24)结构(structure)分区
结构分区显示了一个模块的内部结构。在模块节点中要显示结构分区,可以把图形工具切换到内部模块图,然后拖拽一个属性节点到模块节点上,这时候模块节点会显示结构分区。
结构分区提供了一个把内部结构和模块定义同时显示的机制。
(25)命名(namespace)空间分区
命名空间是一个有名称属性的元素的命名空间。可以把命名空间和磁盘中的“目录”作用类似看待,不同命名空间下面的元素名称可以重复。一个元素完整的名称包括“完整的命名空间”+“::”+“名称”,这个完整的名称称为元素的“完全限定名称”。作为命名空间的元素一般是包,但是模块也可以作为命名空间元素。但是在模块命名空间下面定义的模块元素只是表示是上层模块的“嵌套类”元素,它并不表示“组成”关系。
如果把一个模块拖拽到另外一个模块上面,上层的模块会显示命名空间分区。
(26)图形(image)分区
模块节点也可以显示一个代表模块的图片。通过节点的右键菜单“选择图片”,可以选择一个图片文件,显示在节点下方。
“模块”(Block)主要有四种类型的“属性”。“部件”(parts)、“引用”(references)、“值属性”(value properties)、“约束属性”(constraint Properties)。“部件”的类型一定是另外一种“模块”,而且聚合类型是“组合”;“引用”属性的类型也必须是“模块”,而且聚合类型是“共享”或无;“值属性”的类型是“值类型”(ValueType);“约束属性”的类型必须是“约束模块”(ConstraintBlock)。此外,如上节所述,还有一些更具体的属性类型显示在特定的分区中。如参与属性显示在“参与属性”分区中。但从本质上讲,参与属性只是特殊性类型的引用属性(增加了“参与属性”构造型),端口也只是特殊类型的部件属性。
属性在分区中以一个字符串的形式显示。这个字符串的基本语法如下:
<property> ::= [<visibility>] [‘/’] <name> [‘:’ <prop-type>] [‘[‘ <multiplicity-range> ‘]’] [‘=’ <default>] [‘{‘<prop-modifier > [‘,’ <prop-modifier >]* ’}’]
用中文把上面的语法翻译一下如下:
<属性>定义为:[<可见性>] [‘/’] <名称> [‘: ’<属性类型>] [‘[‘ <多重性范围> ‘] ’] [‘=’ <默认值>] [‘{‘<属性修饰语>[‘, ’<属性修饰语>]*’}’]
上面语法中各部分说明如下:
<visibility>:可见性,表示属性可以被访问的范围。有四种:
+:表示属性是公共的(public),可以被任何模块的行为访问。在SysML标准中所有属性都是公共的,所以在SysML图中一般是不显示可见性的。但是“模块”既可以表示一个具体的硬件产品,也可以表示一个软件的模块。当对软件进行建模的时候,也还是可以使用“可见性”这个概念。
-:属性是私有的(private),仅仅被所属模块的行为访问;
#:属性是受保护的(protected),仅仅对模块及其子类中可见;
~:相同包内可见(package),也就是同一个包中的模块都可以访问这个属性。
‘/’:导出属性的符号。导出的属性,意思是这个属性是其它属性通过计算得到的。例如正方形的“面积”属性是“长”、“宽”属性相乘“导出”的属性。导出属性的值一定是“只读”的,在模块的实例中不能被其它行为方法修改。
<name>:属性的名称。名称也可以为空。为空的时候,可以用它的类型表示这个属性。
<prop-type>:属性的类型,另外一个“模块”、“值类型”或其它能作为类型(Type)的元素。类型也可以为空,表示可以是任何类型。
<multiplicity-range>:多重性。多重性是指一个属性在模型中的数量范围。它的表示方法是“[lowerValue..upperValue]”,翻译一下,既“[下限值..上限值]”。例如“[0..1]”表示最少0个、最多1个;“[4..*]”最少4个、最多不限;“[2]”上限、下限都是2,既必须2个;“[*]”不限个数,既0到多个。
=< default>:属性的默认值;没有赋过值的话,属性就取这个值。可以没有默认值。
<prop-modifier >:属性的修饰语,可以理解为“属性”的“属性”。可能有多个修饰语,每个可能的是如下的值:
<prop-modifier> ::= ‘readOnly’ | ‘union’ | ‘subsets’ <property-name> |’redefines’ <property-name>| ‘ordered’ | ‘unordered’ | ‘unique’ | ‘nonunique’ | ‘seq’ | ‘sequence’ |’id’|<prop-constraint>
‘readOnly’:表示属性是“只读”的。例如导出的属性就是只读的。
‘union’:表示属性是另外的子集属性的并集。
‘subsets’ <property-name>:表示这个属性是另外一个集合属性的子集。例如汽车“前轮”属性是“轮子”属性的子集,定义表示为“前轮:车轮{ subsets 轮子}”,表示2个前轮是汽车所有轮子属性集合中的2个。
’redefines’ <property-name>:重定义了某个属性。在上一篇文章中,我们介绍过“模块”是一种可以“继承”的“类”。作为“继承类”的模块自动拥有了“父类”的所有属性,这些父类的属性称为“继承”的属性。在继承的属性前面用符号“^”标识。继承的属性是父类的属性,不能直接修改它;如果要修改它的定义,必须新定义一个属性“重定义”它。这里“redefines 父类属性”就是这种意思。
‘ordered’:表示属性是有顺序的集合。
‘unordered’:表示属性是没有顺序的集合。
‘unique’:表示是集合的属性中,集合中每个成员都是唯一的。
‘nonunique’: 表示是集合的属性中,集合中每个成员不一定是唯一的。
‘seq’或‘sequence’:表示属性是一个有序的“袋”(bag)。换句话说,就是作为属性的集合,集合中成员是有序的、但不唯一。集合的类型,“无序、唯一”称为“组”(Set);“有序、唯一”称为“有序组”(OrderedSet);“无序、不唯一”称为“袋”(Bag);“有序、不唯一”就称为“序列”(Sequence)。
‘id’:属性是作为模块的ID属性,就是唯一标识模块实例的属性。例如“产品编号”。
<prop-constraint>:属性的约束,一般用“{约束表达式}”来表示约束。例如表达高度属性值必须为>0的约束表示为“{hight>0}”。
在模块中的选择一个属性的时候,属性处于编辑状态时。属性编辑时,可以按照属性的语法直接输入属性,但是只输入基本的语法部分。基本语法部分包括 “属性名称:类型[多重性]”,属性的其它语法部分通过属性框输入。
当属性失去焦点,属性处于显示状态。一般模块中也只显示基本语法。其它语法部分的显示可以通过“模块”的属性框中的“节点属性”中的“可见性”和“特征属性”来控制。如下图所示,对组成部分“硬盘”特征属性的设置和显示:
继承的属性是通过模块之间的泛化关系产生的属性。模块中,默认不显示继承的属性和关联关系生成的属性。如果要显示继承的属性和关联端属性,可以通过模块节点的属性框中的“节点属性”—“显示继承的特征”和“显示关联端属性”来控制。
继承的属性前面有一个“^”符号。继承的属性不能编辑。如果要编辑,需要重定义它,也就是新建立一个属性,并且在“重定义”中输入这个继承的属性名称,则不显示被重定义的继承属性。
关联端属性是在模块之间建立关联关系的时候生成的属性。关联端属性一般显示在关联关系的两端。模型之间的关联关系有三种,“引用关联”、“共享关联”和“组合关联”。这三种关联生成的属性类型不同。“引用关联”两端的属性都是“引用”属性;“共享关联”两端的属性也都是“引用”属性,不过在关系末端(不是菱形箭头的端)生成的引用属性的聚合关系是“共享”;“组合关联”在关系末端(不是实心菱形箭头的端)生成的属性是“组件”(part),聚合关系是“组合”。如果关联是双向的,则两端都生成属性;如果是单向的,仅仅在箭头端生成属性。这个属性的类型,就是靠近关联端的模块。在这个关联端属性节点中,只是输入属性的名称,不需要显示类型。“共享关联”和“组合关联”在靠近菱形箭头的这一端的属性(双向关联时才会产生),默认的多重性是“[0..1]”,可以不显示;另外一端的默认多重性是“[1]”,也可以不显示。多重性是其它情况的话,都要输入、显示。
如下图所示,通过一个“组合关联”和一个“共享关联”生成“计算机”的两个关联端属性“hardDisk”和“monitor”。“hardDisk”属性是一个“部件”属性(由组合关联产生),多重性是“[1..4]”(关联端上的多重性不显示[],如果不是默认值1,需要通过属性框输入上、下限才会显示)。“monitor”属性是一个“引用”属性,多重性是“[1..2]”。它表示计算机可以有1~2个显示器(显示器也可以同时连接其它计算机,所以可以建模为共享聚合关系。)
(1)添加一个模块
a)在图中,通过元素工具栏,拖动模块的图标到图中;或者点击这个图标,在鼠标是十字状态时在图中画出一个节点。
b)在模型浏览器中,通过右键菜单直接增加一个节点的子元素为“模块”。
(2)为模块添加属性和操作等子元素:
a)在图中,通过元素工具栏,拖动相应的图标到模块节点上。
b)在图中,点击元素工具栏后,再点击模块节点中的标题区域。
c)在图中选择模块节点(模块节点四周有小方块状态),然后通过右键菜单添加相应的元素。
(3)删除子元素
a)在图中,选择子元素,然后通过右键菜单“删除”来删除子元素。
b)在图中,选择子元素,直接按删除键删除子元素。但此时整个模块节点不能是选择状态(模块节点四周有空心的小方块),否则删除的是整个节点。
(4)编辑属性和方法
模块分区中的元素,代表模块元素的一类特征(Feature)(本文档中称为模块元素的子元素)。
模块的属性主要有4类:约束属性(Constraint property)、组成部分属性(Part property)、值(Value property)属性和引用属性(Reference property)。这四种属性分别规定了属性的具体类型分别为约束(Constraint)、模块(Block)而且和父级的模块是组合关系、值类型(ValueType)、模块而且和父级模块不是组合关系。除了这四种属性之外,一般属性(Property)分区没有规定属性的类型,可以是任何类型的属性。
模块还有表示方法的操作(Operation)分区和的表示行为特征的类目行为(classifier behavior)分区、拥有行为(owned behaviors)分区。
这些属性和方法的编辑,可以选择相应子元素后,子元素的状态会变为编辑状态。编辑完成之后,子元素失去焦点之后转为显示状态。这些属性或方法的特性的编辑,也可以通过属性框进行编辑。
(5)添加端口
模块有表示接口关系的端口分区。模块的端口可以显示为边上的小方块,也可以显示在一个分区中。
为模块在端口分区中增加端口属性,可以拖动比较窄的端口属性图标到模块节点中,或通过右键菜单。
为模块添加端口节点,拖动小方块形状的端口图标到模块节点内部。添加其它类型的端口节点,如嵌套端口节点、带分区的端口节点,也是拖动相应图标到模块节点内部。在嵌套的端口中再增加端口,拖动端口图标到嵌套端口中。
端口的方向:可以通过属性框来设置。如下图所示,为名称为p1的端口设置方向为双向:
(6)添加自定义分区
选择模块节点之后,通过右键菜单“添加—分区”,添加一个自定义分区。选择自定义分区的标题,再点右键菜单,可以添加任何类型的属性或操作。
名称:可以修改分区的名称,也可以通过属性框更改名称。
删除:可以通过右键菜单删除这个分区。删除分区的时候,系统会讯问“是否保留分区中的属性”。如果选择“是”,则分区中的属性按照各自的分类,显示到默认的分区中;如果选择“否”,则分区中的属性一起删除。
是否显示:在节点的属性框中,展开“自定义分区”,对具体的某个分区,可以设置这个分区是否显示;
更改属性(或分区中其它特征)的分区:选择分区中的属性,右键菜单“更改分区”,可以重新设置属性所属分区。
隐藏个别属性的方法:如果部件、引用或值属性分区中的某个属性不想显示,可以增加一个自定义分区,把这个不显示的属性通过“更改属性的分区”移动到自定义分区,并设置这个自定义分区不显示。
MBSES用户使用说明书