UML用例类时序图详解.docx
《UML用例类时序图详解.docx》由会员分享,可在线阅读,更多相关《UML用例类时序图详解.docx(16页珍藏版)》请在冰豆网上搜索。
UML用例类时序图详解
用例图:
描绘不同系统用户群是如何同这个系统交互。
用例定义和描述用户从系统中获取价值的各种方法。
创建一个用例模型需要三个步骤:
1确定使用这个系统的人群
2确定这些人群是如何从系统中获取价值
3用一个简单易懂的视图来描述这些用户以及他们如何使用系统
第一步:
寻找参与者(actor)
确定使用该系统的各种人群,一种人群称为参与者(actor),使用这个系统或被这个系统使用的其他系统也是参与者。
参与者定义:
指在某个系统的外部并和该系统交互的一群人或一个系统。
例:
下列小组都是参与者
1银行客户和柜员分别是单独的参与者,因为他们有着不同的需求和权限
2大多数游戏系统中,男人和女人没必要分成单独的参与者
3学生和登记管理员是单独的参与者,有不同的需求和访问
第二步:
寻找用例(usecase)
系统为参与者提供一个独立的价值所采用的方式称之为用例.
用例必须是集中的,并有一个明确的目标
如果用例满足以下条件,则是集中的:
1用例应带来独立的好处
2可以用20-30个单词来描述这个好处
3参与者能通过一次会话完成该用例
例:
银行系统有输入帐号、选择帐号、取款、存款、选择源帐号、选择目标帐号、资金转移等功能,如果将这些动作都作为用例则显得太细,不能满足独立条件。
比如,没有一个用户会在选择一个帐号后就满意的离开!
但是,如果只为一个用例---资金管理,则又显得太笼统。
好的用例应提供一个具体的用途!
取款、存款、转账等都可以是好的用例,均提供了具体的用途!
第三步
描述参与者与用例
UML中,参与者用棒形人表示,用例用带标记的椭圆来表示
参与者指向用例的带箭头的实线表示这个参与者触发该用例,比如:
利用用例描述需求:
1用例描述
说明用例的概况和特征,比如,前置条件、后置条件、性能需求、安全要求、部署约束等。
前置条件—包括参与者启动这个用例之前必须完成的所有其他用例
后置条件—包括这个用例对系统所作的所有改变
部署约束—描述访问这个用例的所有约束
2事件流
描述参与者在完成用例的过程中发生的一系列的交互行为。
银行ATM:
1用户插入卡,输入PIN,系统显示包含用户名的欢迎信息,并提供取款、存款、转账等选项
2用户选择取款,系统显示所有可供选择帐户
3用户选择帐户,系统要求用户输入金额
4用户输入一个正整数,系统询问用户数额是否正确
5用户确定金额是正确的,系统显示感谢信息,取出钱、打印帐单并返回客户的卡
以上就是一个事件流,但描述的是一切都正常运行时的交互情况,还有一些可能的其他情况的事件流,所以,事件流分为三种:
1正常或基线事件流,以上事件就是这种事件流
2可选事件流
描述由参与者引起的变更,比如,参与者放弃取款、输入错误数据等,一个用例可能有几种不同的可选事件流,以上取款的可选事件流包括输入一个无效的PIN或者取款金额过多等。
3异常事件流
由系统引发的事件,比如网络故障、磁盘错误等
用户操作
操作结果
1.用户插入卡,输入PIN
2.用户选择取款
3.用户选择帐户
4.用户输入一个正整数
5.用户确定金额是正确的
6.输入一个无效的PIN
7.磁卡失效
主流程
1.系统显示包含用户名的欢迎信息,并提供取款、存款、转账等选项
2.系统显示所有可供选择帐户
3.系统要求用户输入金额
4.系统询问用户数额是否正确
5.系统显示感谢信息,取出钱、打印帐单并返回客户的卡
备选流
6.1系统提示输入错误
异常流
7.1系统提示卡失效,无法适用
这是一个用例图————————————————————
—————————————————————————————
3活动图
集中显示一个用例所有事件流的UML图。
活动图描述一个开始状态、系统执行的活动、执行下一个活动时需做的判断以及一个或多个结束点。
*实心的圆圈代表用例的开始
*圆角的矩形代表系统执行的活动
例
以下是上面ATM取款事件流的活动图:
注意:
一个用例可以被多个参与者执行,反之,一个参与者可以执行多个用例
类图
标记静态内容及其类之间的关系。
在一个类图中,我们能够查看一个类的成员变量和成员函数。
我们也能查看一个类是否继承自另外一个类,是否拥有对另外一个类的引用。
简而言之,我们能够描绘出类之间的源代码依存关系。
Figure3-1展现了一个类图的最简单的形式,这个名叫Dialler的类代表一个简单的长方形。
这个图代表的东西并不比右边的代码要多。
这是表现一个类的最常用的方法,大多数图的类有一个能够清楚表达的命名就可以了。
一个类的图像符号被细分成几个框格,最上面部分表示类的名字,第二个框格表示类的变量,第三个框格表示类的方法。
Figure3-2展示所有的框格及对应的源代码。
请注意在类图像符号里,在变量和函数的前面一个字符,一个“-”表示变量或函数是私有(private),“#”表示变量或函数是受保护(protected)的,“+”表示变量或函数是公开的(public)。
紧接在变量或参数名称的冒号(:
)号之后,表示了变量的类型或一个函数的参数的类型。
同样地,函数的返回值的类型是在函数后面的冒号之后反映的。
1关联(Association)
类之间的关联大多用来表示变量实例持有着对其他对象的引用。
举一个例子,在Figure3-3中,我们看到在Phone和Button之间一个关联,这个箭头的方向告诉我们是Phone持有着Button的引用。
靠近箭头的地方标有着变量实例的名称,箭头附近的数字告诉我们被引用的数量。
多重性
这个箭头附近的数字表示连接到其他对象的关联的数量。
在以上的Figure3-3中,我们看到有15个button对象被连接到Phone对象。
在下面的Figure3-4中,我们将看一种没有数量限制的情况,一个PhoneBook被连接到许多的PhoneNumber对象。
这个星号(*)意味着非常多的数量。
在Java中通常用一个Vector、一个List或其他容器类型来实现。
这里有一些允许的形式:
数字精确的数量
*或0..*0到无数
0..10个或1个,在Java中经常用一个空的引用来实现
1..*1个到无数个
3..53个到5个
1.1聚合(Aggregation)
聚合是关联的一种特殊形式,它意味着一种整体/部分(whole/part)的关系。
不幸的是,UML并没有为这种关系提供一个强大的定义,由于不同的程序员和系统分析员为这种关系采用了他们自己喜欢的定义方式导致了混淆。
由于这个原因,我将不使用任何这种关系,我建议大家也避免这样做!
UML给我们的关于聚合的硬性规定是相当简单的。
一个整体不能是它自己的一部分。
因此,实例不能形成聚合回路,一个单独的对象不能够成为它自己的聚合,两个对象不能互相聚合,三个对象不能形成一个聚合环,如Figure3-15所示:
1.2组合(Composition)
组合是一种特殊的聚合形式,如Figure3-16所示。
再次声明,它的UML实现还是无法从关联中区分出来。
不过,这一次不是定义缺乏的原因论是JavaC++程序中都很少用到这种关系,换句话说,它用得极少。
规则:
1一个被组合的对象的实例不能同时属于两个系主。
在Figure3-17中的对象是非法
2系主负责被组合的对象的生命周期的管理。
如果系主被销毁,被组合的对象也必须跟着一起被销毁,如果系主被复制,被组合的对象也必须跟着一起被复制。
1.3关联构造类型
关联能够通过带标记的构造型来改变它的意义。
Figure3-20显示了我经常用到的一些。
«creates»的构造型指明关联的目标对象是被源对象创建的象,然后将它传送给系统的其他对象。
在这个例子中我显示一个典型的工厂(factory)模式。
«local»构造型用于源类创建了一个目标对象的实例,把它当做一个本地变量。
它暗示被创建的实例不能在创建它的成员函数之外存活。
因此,它不被任何实例变量持有,也不能以任何一种方式传递给系统的其他部分
«parameter»构造型显示了源类获取了目的实例的访问入口,尽管是通过它的成员函数的参数的方式进行的。
另外,这暗示当成员函数返回时,源对象便忘了这个目标对象。
这个目标对象没有在实例变量中被保存。
«delegates»构造型不是一个标准的UML组成部分,它是我创建的,不过我经常用它。
因此我想它最好包括在这里。
当源类传递目标对象的一个成员函数调用时,能够用到它。
有许多的设计模式用到了这种技术,如PROXY、DECORATOR和COMPOSITE7。
因为我经常用它们,我觉得这个标记非常有用
2继承(Generalization)
正指着Employee的小箭头表示了继承(inheritance)。
如果你画箭头不小心,可能就很难说清是继承还是关联了,尽量小心一点。
我经常用垂直方向的箭头表示继承关系,用水平方向的箭头表示关联。
在UML中,继承箭头是指在基类上的。
3实现(Realization)
UML有一个特殊的符号,用来说明一个Java类和一个Java接口之间不同类型的继承Figure3-6所示,是一个虚线继承箭头。
4依赖(Dependency)
5内部类
内部类在UML中用一个带十字圆圈的关联标记来表示。
匿名内部类UML在这里还没有提供官方的支持,我发现用如Figure3-22的标记能够比较好地为我工作,这种标记简洁而描述完整。
匿名内部类用有一个«anonymous»构造型的嵌入类来展示,被实现的接口的名称也被给出。
序列(Sequence)图
序列图是一种被使用UML的人使用的最常用的动态建模画法,就像你期望的那样,UML提供了一大堆有趣的东西帮助你画出那种很难理解的图,注意,应节制的使用。
对象、生命线、消息
Figure4-1展示了一个典型的序列图,有关协作的对象被放置在图的顶部,这个人样图在左边表示一个匿名对象(参与者),它是所有进入和离开这个协作的消息的源头和汇集点。
这条垂立在对象或参与者下面的虚线叫做生命线(lifelines)。
一个从一个对象被发送到另外一个对象的消息被画成一个两条生命线之间的箭头。
每个消息都被标记出名称。
参数被画在消息名称后面的括号里或是一个数据标记(datatokens,一个以小圈结束的箭头)之后。
时间(Time)是在垂直方向,因此越是下面的消息是越晚被发送。
在LoginServlet对象生命线上的小框框叫做活动(Activation),活动是可选的,大多数图都不需要它们。
它们表示函数的执行时间。
在这个例子中表示login函数执行时间长短。
离开这个活动往右的两个消息被login方法发送出。
那个没有标记的箭头表示login函数返回给参与者,传回一个返回值。
注意在getEmployee消息中的返回变量e,它表示getEmployee的返回值。
注意这个Employee对象也叫做e,你已经猜到了,它们是同一个东西!
getEmployee的返回值是一个Employee对象的引用。
创建和销毁
我们能够用Figure4-2中约定的画法在一个序列图中展示一个对象的创建。
一个没有标记的消息终止在一个被创建的对象上,而不是它的生命线上。
我们期望ShapeFactory如Listing4-2所示那样被实现。
对应的代码:
Figure4-3显示了我们如何在UML去标记它,一个对象的生命线被声明终止在一个在“X”上。
消息箭头终止在这个”X”表示声明一个对象被垃圾回收器处理
Listing4-3说明了我们从上图期望的实现,注意那个clear方法将topNode变量设置为null.因为这个TreeMap仅是一个持有TreeNode实例的一个引用的对象,它被声明给垃圾回收器去处理。
简单的循环
你可以通过在一个重复的消息周围画一个方框的方式在一个UML图中表示一个简单的循环。
这个循环条件能放置在方框中的任何地方,经常被放置在左下角,见Figure4-4。
异步消息
通常,当你发送一个消息给一个对象时,你希望等到接收消息的对象完全执行完成后才获回控制。
以这种方式传递的消息为同步消息。
不过,在一个分布式和多线程的系统中,将消息发送后立即获回控制权,而接收消息的对象在另外一个控制线程中执行的情况是可能的。
这种消息称为异步消息(asychronousmessage)。
Figure4-11显示一个异步消息,注意是用空心的箭头代替了实心箭头。
回头看看本章所有其他的序列图,这都是被画成实心的同步消息。
稍微不同的箭头有完全不同的行为表现。
Listing4-5和listing4-6说明了对应于Figure4-11的源代码。
Listing4-5表示一个有关Listing4-6中的Log类的一个单元测试。
注意到logMessage函数在排队了一个消息后立即返回。
注意,这个消息实际上被一个由构造器开始的完全不同的线程处理了。
这个LogText类来确认logMessage方法是异步运行,首先检查这个消息被记录但没有执行,然后让这个处理器到另外一个线程,最后检验这个消息被处理了并从队列中移除了。
多线程
异步消息暗示着多线程控制。
我们在UML图中通过带一个线程标识的消息名称标记,来显示几个不同的线程控制,如Figure4-12。
注意,消息名称前置一个像T1的标识名称,紧跟在冒号后后面。
这个标识命名了发送消息的线程。
在这个图中,这个Log对象被线程T1创建并操纵。
在Log对象中实现消息记录、运行的线程命名为T2。
就像你看到的一样,这个线程名称并不需要对应到代码中去。
上面的Listing4-6并没有命名线程T2。
然而,这线程标识对于图来说是有好处的。