模型
- 功能模型:从用户的角度展示系统的功能,包括用例图。
- 对象模型:采用对象,属性,操作,关联等概念展示系统的结构和基础,包括类别图、对象图。
- 动态模型:展现系统的内部行为。包括序列图,活动图,状态图。
图形
UML 2.2中一共定义了14种图示(diagrams)。为方便了解,可分类成右侧的结构。
结构性图形(Structure diagrams) 强调的是系统式的建模:
- 类图 (Class Diagram)
- 组件图(Component diagram)
- 复合结构图(Composite structure diagram)
- 部署图(Deployment diagram)
- 对象图(Object diagram)
- 包图(Package diagram)
行为式图形(Behavior diagrams) 强调系统模型中触发的事件:
- 活动图(Activity diagram)
- 状态机图 (State Machine diagram)
- 用例图 (Use Case Diagram)
沟通性图形(Interaction diagrams), 属于行为图形的子集合,强调系统模型中的资料流程:
- 通信图(Communication diagram]]
- 交互概述图(Interaction overview diagram) (UML 2.0)
- 循序图(Sequence diagram)
- 时间图(UML Timing Diagram) (UML 2.0)
对于结构而言
对于行为而言
对于关系而言
顺序图
顺序图是交互图的一种形式,它显示对象沿生命线发展,对象之间随时间的交互表示为从源生命线指向目标生命线的消息。顺序图能很好地显示那些对象与其它那些对象通信,什么消息触发了这些通信,顺序图不能很好显示复杂过程的逻辑。
生命线
一条生命线在顺序图中代表一个独立的参与者。表示为包含对象名的矩形,如果它的名字是"self",则说明该生命线代表控制带顺序图的类元。
有时,顺序图会包含一个顶端是执行者的生命线。这情况说明掌握这个顺序图的是用例。健壮图中的边界,控制和实体元素也可以有生命线。
消息
消息显示为箭头。消息可以完成传输,也可能丢失和找回,它可以是同步的,也可以是异步的,即可以是调用,也可以是信号。在下图中,第一条消息是同步消息(标为实箭头)完成传输,并隐含一条返回消息。第二条消息是异步消息 (标为实线箭头),第三条是异步返回消息(标为虚线)。
执行发生
向下延伸的细条状矩形表示执行事件或控制焦点的激活。在上图中有三个执行事件。第一个是源对象发送两条消息和收到两条回复。第二个是目标对象收到一条同步消息并返回一条回复。第三个是目标对象收到一条异步消息并返回一条回复。
内部通信
内部消息表现为一个操作的递归调用,或一个方法调用属于同一个对象的其他方法。显示为生命线上执行事件的嵌套控制焦点。
迷路消息和拾取消息
迷路消息是那些发送了却没有到达指定接收者,或者到达的接收者不再当前图中。拾取消息是收到来自那些未知的发送者,或者来自没有显示在当前图的发送者的消息。它们都表明是去往或来自一个终点元素。
生命线开始与结束
生命线可以在顺序图时间刻度范围内创建和销毁,在下面的例子中,生命线被停止符号(叉号)终止。在前面的例子中,生命线顶端的符号(Child)显示在比创建它的对象符号(parent)沿页面要低的位置上。下图显示创建和终止对象。
时间和期限约束
消息默认显示为水平线。因为生命线显示为沿屏幕向下的时间通道,所以当给实时系统建模,或是有时间约束的业务过程建模,考虑执行动作所需时间长度是很重要的。因此可以给消息设置一个期限约束,这样的消息显示为下斜线。
复合片段
如前面所说,顺序图不适合表达复杂的过程逻辑。在一种情况下,有许多机制允许把一定程度的过程逻辑加入到图中,并把它们放到复合片段的标题下。复合片段是一个或多个处理顺序被包含在一个框架中,并在指定名称的环境下执行。 片段可以是:
- 选择性片段 (显示 “alt”) 为 if…then…else 结构建模。
- 选项片段 (显示 “opt”) 为 "switch"(开关) 结构建模。
- 中断片段对被处理事件的可选择顺序建模,而不是该图的其他部分。
- 并行片段(显示 “par”) 为并发处理建模。
- 弱顺序片段 (显示 “seq”) 包含了一组消息,这组消息必须在后继片段开始之前被处理。但不会把片段内消息的先后顺序强加到不共享同一条生命线的消息上。
- 严格顺序片段 (显示 “strict”) 包含了一系列需要按照给定顺序处理的消息。
- 非片段 (显示 “neg”) 包含了一系列不可用的消息。
- 关键片段 具有关键部分。
- 忽略片段 声明一个没有意义的消息,如果它出现在当前上下文中。
- 考虑片段与忽略片段相反,不包含在考虑片段内的消息都应该被忽略。
- 断言片段 (显示 “assert”)标明任何没有显示为声明操作数的顺序都是无效的。
- 循环片段 包含一系列被重复的消息。
下图显示的是循环片段:
这也是一个类似于复合片段的交互发生。 交互发生被其他图参考,显示为左上角带"ref",将被参考图名显示在方框的中间。
门
门是连接片段内消息和片段外消息的连接点。 在EA中,门显示为片段框架上的小正方形。作用为顺序图与页面外的连接器。 用来表示进来的消息源,或者出去消息的终点。下面两个图显示它们在实践中的使用。注意:" top level diagram"中的门用消息箭头指向参考片段,在这里没有必要把它画成方块。
部分分解
一个对象可以引出多条生命线,使得对象内部和对象之间的消息显示在同一图上。
状态常量 / 延续
状态常量是生命线的约束,运行时始终为"真"。显示为两侧半圆的矩形,如下图:
延续虽与状态常量有同样的标注,但是被用于复合片段,并可以延伸跨越多条生命线。
**********************************************************
UML状态图描述一个实体基于事件反应的动态行为,显示了该实体如何根据当前所处的状态对不同的时间做出反应的。通常我们创建一个UML状态图是为了以下的研究目的:研究类、角色、子系统、或组件的复杂行为。建模实时系统。
通用准则
当行为的改变和状态有关时才创建状态图。
敏捷建模( AM) ( Ambler 2002)的原则--最大化项目干系人的投资--建议你只有当模型能够提供正面价值的时候才创建模型。 如果一个实体,比如一个类或组件,表示的行为的顺序和当前的状态无关,那么画一个UML状态图可能是没有什么用处的。例如一个SurfaceAddress类就很简单,表示了那些你将会在系统中显示和操作的数据,因此一个UML状态图就没有任何相关之处。而一个Seminar对象就非常的复杂,学生注册这样一个事件将会根据它的当前状态有不同的反应,就像你在图1中看到的。
图⒈班级注册的一个UML状态图。
把初始状态放置在左上角。
如你在图1所见的,初始状态被建模成一个实心圈,把初始状态放在左上角反映西方人的阅读文化的习惯。
把最终状态放置在右下角。
如你在图1所见,最终状态被建模为一个带边界的实心圆。把最终状态放右下角反映了西方的文化的从左到右,从上到下的阅读习惯。
状态指南
状态是一个实体的行为模式的某个阶段。 状态的表示是通过实体的属性值。 例如,在图1中,当seminar被标记为open,并且存在空位的时候,seminar就处于Open For Enrollment的状态。
状态名称要简单但应具有描述性。
象Open For Enrollment和Proposed这种的状态名称很容易理解,从而提高了图⒈的沟通价值。理论上状态名称应该是现在时,但是用过去式写成的诸如Proposed的名称要比用现在时写成的诸如Is Proposed的名称好的多。
避免"黑洞"状态。
黑洞状态是那种只有变换进来但没有任何变换发出的状态,这种情况要么由于该状态是一个最终状态,要么就是你已经错过了一个或多个变换变换。
避免"奇迹"状态。
奇迹状态是那种只有变换发出但没有任何变换进来的状态,这种情况要么由于该状态是一个起点,要么就是你已经错过了一个或多个变换变换。
子状态建模指南
为复杂的目标建模子状态。
图1中展示的UML状态图是不完整的,因为它没有建模Seminar的post - enrollment(注册后)状态。 图2建模了一个Seminar的完整的生命周期,把图1描述为一个新的包括子状态集合的Enrollment的复合状态,也称作超状态。 注意按理说你会像图1的模型那样处理标记,但为了简化起见在原先变换上的标记都没有包括在内。当一个现有状态表现出复杂的行为时,建模子状态就是有意义的,从而促使你来研究它的子状态。 当几个现有状态共用一个通用的入口条件或出口条件( Douglass 1999)时,引入超状态是有意义的,在图1中你可以看到所有的状态共用一个通用的closed变换,以到达最终状态。
图⒉Seminar的完整生命周期
把通用的子状态变换放在一起
和图1中每一个子状态都拥有一个cancelled变换不同,在图2中你可以看到cancelled变换仅用于描述Enrollment超状态,这使图形得到简化。 如果子状态都共享一个入口变换或出口变换,都可以使用一个同样的方法。 变换上的警戒点和动作(如果有)也应该使相等的。
为复杂的实体创建一个分层的状态图
虽然这种表现子状态的方法是很好使的,但是最终的图可能变得相当复杂--我们只要设想一下如果Being Taught状态也有子状态的话,图2会变成什么样就知道了。 一个替代的方法是创建一个分层的UML状态图。 例如,图3表示高阶视图,而图1描述了一个细节视图。这种方法的好处是如果需要的话,马上就可以建立一张详图来研究Being Taught状态。
图⒊Seminar的高阶状态图。
最高阶的状态图总有初始态和最终态
一个高阶的UML状态图,例如图2描述的这样,应该表示实体的完整的生命周期,包括"出生"和最后的"死亡"。 低阶的图未必包含初始状态和最终状态,特别是那些建模一个实体的生命周期的"中间状态"的图。
变换和动作
变换是从一种状态到另一种状态的序列,它可能是通过一个事件触发的。简而言之就是被建模的实体的内部或外部的行为。 对一个类来说,变换一般是将会导致状态的重要改变的操作调用的结果,因此我们需要了解一点,并不是所有的方法调用都会导致变换产生的,这一点非常重要。 一个动作就是某个东西,对类来说就是一个操作,被建模的实体所调用的操作。
用实现语言的命名规则命名软件动作
图1中的动作遵循Java操作的命名规则( Vermeulen et. 2000),因为系统使用<java做为实现语言,如果我们的目标是两外一种语言,那么我们也需要遵循适当的命名规则。
用叙述性文字命名角色动作
UML状态图可用于建模非软件实体的生命周期,特别是UML图上的角色。 例如学生角色就可能有诸如Accepted、Full Time、Part Time、Graduated、Masters、Doctoral、和Post - Doctoral等状态,以显示各人的不同行为。 当你在建模现实世界的角色时,与软件中Student类不同的是,状态间的变换最好是使用叙述性文字来描述,例如drop seminar和pay fees,而不是dropSeminar ()和payFees (),因为现实生活中的人是做事情,而不是执行操作。
只有对所有的入口变换都合适时才注明入口动作
在图1中你可以看到Closed To Enrollment状态的入口中操作notifyInstructor ()都是经由entry/动作标记来调用的。 这暗示着每次进入状态时都需要调用该操作,如果你不希望每次都发生,那么就把动作关联到特定的入口变换。 例如,addStudent ()动作是在student enrolled变换到Open For Enrollment变换发生,而在到opened变换则不会发生,这是因为每次你在进入该状态并不需要增加一个学生。
只有对所有的出口变换适合时才注明出口动作
出口动作,用exit/标记来表示,工作方式类似于入口动作。
只有当你想终止并再进入该状态时才建模递归变换
一个递归的变换是那些两个端点都拥有相同状态的变换。 一个重要的暗示是实体从状态出来,又回到原有的状态,因此,那些由于entry/或exit/动作标记而被调用的任何一种操作都可能被自动调用。 图1的Open For Enrollment状态就是这种递归变换的例子,因此当前班级大小就在入口处被记录下来。
用过去式命名转换事件
图1中的转换事件,例如seminar split和cancelled,是使用过去式命名的,反映了这样一个事实:变换是事件的结果--因为事件发生在变换之前,因此应该用过去式命名。
把转换标记放在接近源状态的地方
虽然图1比较复杂,变换标记尽可能放在靠近来源的地方,例如seminar split和student enrolled。 Furthermore, the labels were justified (left and right respectively) to help visually place them close to the source state.
以转换方向为基础放置变换标记
为了更易于判断哪个标记和变换是一起的,按照如下的规则来放置变换标记:
在变换线条上的从左到右。
在变换线条下的从右到左。
变换线条右边的往下。
变换线条左边的往上。
警戒点
一个警戒点是为了穿过一个转换而必须为真的一个条件。
警戒点不应该重叠
离开状态的相似变换上的警戒点必须彼此一致。 举例来说,x <0, x = 0,以及x > 0的警戒点是一致的,而x < = 0和x > = 0的警戒点就不是一致的,因为他们重叠了,它并没有明确的指出当x为0时将发生什么。在图1中,你可以看到警界点的一致性,从填写注册表活动出发的该学生划线变换上的警戒点没有重叠,决策点上的警戒点也一样。
为可视化的定位警戒点而引入接合点。
在图2中你可以看到从Being Taught触发student dropped事件存在两个变换,而图3中仅有一个,变换被合并了,因此我们需要一个接合点(填满的圆)。 这种方法的好处是现在图上的两个警戒点更彼此接近了,更容易看出警戒点是否重叠。
警戒点不必配套
一个状态的变换警戒点有可能是不完整的。例如,一个bank account对象可能从Open状态变换到Needs Authorization状态,这时需要一个大额存款"large deposit"的警戒点。可是,一个带有"small deposit"的警戒点的deposit变换可能并不需要建模,它是被隐含的,我们遵循了AM的实践--简单的描述模型和仅仅包括相关的信息。
一致的命名警戒点
图1包含了诸如seat available和no seat available的警戒点,两个警戒点的描述是一致的。 然而,诸如seats left、no seat left、no seats left、no seats available、seat unavailable之类的描述就是不一致,而且难于理解的。