UML为建立系统模型提供了一整套建模机制,使用用例图、协作图、顺序图、活动图和状态图等可以从不同的侧面、不同的抽象级别为系统建立模型。
1,其中用例图主要用于为系统的功能需求建模,它主要描述系统功能,也就是从外部用户的角度观察,系统应该完成哪些功能——有利于开发人员以一种可视化的方式理解系统的功能需求。
2,用例图是对系统功能的一个宏观描述——画好用例图是由软件需求到最终实现的第一步,也是最重要的一步。
用例图的概念
一,定义
1,由参与者(Actor)、用例(UseCase)以及它们之间的关系构成;
2,用例图的元素:
(1)角色:人员角色——人、事;
角色不一定局限于人,还可以是事物、事儿
(2)用例:功能的描述;
每一个用例描述了一个完整的系统服务。
(3)关系:执行者和用例的关系——
关联关系(常用构造型:include、extend);
依赖关系:使用关系;
泛化关系:继承关系;
实现关系;
3,主要属性
事件流;
前置条件;
后置条件;
特殊要求;
扩展点;
问题说明;
(1)事件流:描述一个用例在执行时执行者与系统之间的交互过程。这个过程包括多个分支
基本流:对用例中常规和预期路径的描述;
备选流:由于受到其他因素影响,用例执行了其他的路径;
(2)前置条件:该用例执行的前提条件,用来描述在什么条件下可以执行一个事件流;
(3)后置条件:说明用例结束时系统的状态;
前置条件和后置条件可以用于用例的验证和评审。
4,用例的粒度和范围
级别:
(1)概述级
(2)用户目标级
(3)子功能级
例子:图书馆管理系统建模
概述级:用例:图书管理
用户目标级:用例:借书、还书
子功能级:用例:借书、还书、验证用户身份
(include:附用关系)
5,用于描述系统功能的动态视图。
6,进行用例建模时,所需要的用例图数量是根据系统的复杂度来衡量的。
一个简单的系统中往往只需要一个用例图就可以描述请所有关系;但是对于复杂的系统,一张用例图显然是不够的,,这时候需要用多个用例图共同描述。
但是,一个系统的用例图也不应过多。
7,对于较复杂的大中型系统,用例模型中的参与者和用例会大大增加,这样的系统往往会需要几张甚至几十张用例图。
为了有效地管理由于规模上升而造成的复杂度,对于复杂的系统还会使用包(Package)——UML中最常用的管理模型复杂度的机制。
8,在用例建模中,有时为了更加清楚地描述用例或参与者,会使用到注释。如下图:
(注意:注释和包都不是用例图的基本组成要素。不过在用例建模过程中可能会用到这两个要素)
二,用例的作用
1,用例图是需求分析中的产物(用例图用在需求分析阶段)。
主要作用是描述参与者和用例之间的关系,帮助开发人员可视化地了解系统的功能。
2,借助于用例图,系统用户、系统分析人员、系统设计 人员、领域专家能够以可视化的方式对问题进行讨论,减少了大量交流上的障碍,便于对问题达成共识。
3,用例方法是完全从外部来定义系统功能的,它把需求和设计完全分离开来,不用关心系统内部是如何完成各种功能的,系统就好像一个黑箱子。
4,每一个用例描述了一个完整的系统服务。
用例图的组成
用例的4个组成要素:参与者(角色)、用例、系统边界、关联。
一,参与者
一,参与者
1,概念:(1)参与者是指存在系统外部并直接与系统进行交互的人、系统、子系统或类的外部实体的抽象。
(2),每个参与者可以参与一个或多个用例,每个用例也可以有一个或多个参与者。
(3),参与者不仅是人,参与者代表的是一个集合,通常一个参与者可以代表一个人、一个计算机子系统、硬件设备或者时间等。
(注:#人是其中最常见也是最容易理解的参与者;
#一个系统也可以作为参与者,大家去商场购物,往往会采用刷卡付费的方式,这时候就需要商场的管理程序和外部的应用程序建立联系来验证信用卡以便付款,其中外部信用卡程序就是一个参与者,是一个系统;
#而在有的系统中,一个进程也可以作为参与者,例如:时间。如果家里开通上网包月的话,当包月时间快结束的时候,系统就会提示相关服务人员,再由这些人员通知包月到期的用户。由于时间不在人的控制范围内,因此也是一个参与者)
(4),注意:参与者虽然可以代表人或事物,但参与者不是指人或事物本身,而是表示人或事物当时所扮演的角色,例如:小王是银行的工作人员,他参与银行管理系统的交互,这时他既可以作为管理员这个角色参与管理,也可以作为银行用户来取钱,在这里小王扮演了两个角色,是两个不同的参与者,因此不能将参与者的名字表示成参与者的某个实例,例如小王作为银行用户来取钱,但是参与者的名字还是银行用户而不能是小王。
(5),参与者还可以划分为主要参与者和次要参与者:主要参与者值得是执行系统主要功能的参与者;次要参与者指的是使用系统次要功能的参与者。
标出主要参与者有利于找出系统的核心功能,往往也是用户最关心的功能。
2,参与者的确定
(1)在获取用例前首先确定系统的参与者,寻找参与者可以从一下问题入手:
#系统开发出来后,使用系统主要功能的是谁?
#谁需要借助系统来完成日常的工作?
# 系统需要从哪些人或其他系统中获得数据?
#系统会为哪些人或其他系统提供数据?
#系统会与哪些其他系统交互?其他系统可以分为两类:一类是该系统要使用的系统;二类是启动该系统的系统,包括计算机系统和计算机中的其他应用软件。
#系统是由谁来维护和管理的,以保证系统处于工作状态?
#系统控制的硬件设备有哪些?
#谁对系统产生的结果感兴趣?
(2)注意:寻找参与者的时候不要把目光只停留在使用计算机的人身上,直接或间接的与系统交互的任何人和事都是参与者。
(3)由于参与者总是处于系统外部,因此他们可以处于人的控制之外。
(4)例子:看一个比较特殊的参与者—系统时钟,有时需要在系统内部定时地执行一些操作,如检测系统资源的使用情况、定期生成统计报表等。这些操作并不是有外部的人或系统触发的,它是由一个抽象出来的系统时钟或定时器参与者来触发的。
3,参与者间的关系
由于参与者实质上也是类,所以它拥有与类相同的关系描述,即参与者之间主要是泛华关系(继承关系)
泛华关系的含义是把某些参与者的共同行为提取出来表示成通用行为,并描述成超类,如图1:
例子:在需求分析中很容易碰到用户权限问题,对于一个公司来说,普通职员有权限进行一些常规操作,而销售经理和人事经理在常规操作之外还有权限进行销售管理和人事管理,用例图如图2;
在这个例子中会发现销售经理和人事经理都是一种特殊的用户,他们拥有普通用户所拥有的全部权限,此外他们还有自己独有的权限。
这里可进一步把普通用户和销售经理,人事经理之间的关系抽象成泛华关系。如图3:
图2:
图3:
二,用例
1,概念:
(1)用例(Use Case)是参与者(角色Actor)可以感受到的系统服务或功能单元。
(2)它定义了系统是如何被参与者使用的,描述了参与者为了使用系统所提供的某一完整功能而与系统之间发生的一段对话。
(3)用例最大的优点就是站在用户的角度上(从系统的外部)来描述系统的功能。它把系统当做一个黑箱子,并不关心系统内部是如何完成他所提供的功能,表达了整个系统对外部用户可见的行为。
(4)每个用例在其所属的包里都有唯一的名字,该名字是一个字符串,包括简单名和路径名。
用例的路径名就是在用例名前加上用例所属的包的名字,如图4:
图4:
(5)用例和参与者之间也有关系:关联关系(Association),又称作通信关联(Communication Association)。
2,用例的识别
(1)任何用例都不能在缺少参与者的情况下独立存在。同样,任何参与者也必须要有与之关联的用例,所以识别用例的最好方法是从分析参与者开始,在这个过程中往往会发现新的参与者。当找到参与者之后可以根据参与者来确定系统的用例,主要是看各参与者如何使用系统,需要系统提供什么样的服务,可以通过以下问题来寻找用例:
#参与者系统系统提供什么功能?
#参与者是否会读取、创建、修改、删除、存储系统的某种信息?如果是的话,参与者是如何完成这些操作的?
#参与者是否会将外部的某些事件通知给系统?
#系统中发生的事件是否通知参与者?
#是否存在影响系统提供的外部事件?
(2)用例图的主要目的是帮助人们了解系统功能,便于开发人员与用户之间的交流。
3,用例的粒度
4,用例规约
5,用例之间的关系:
为了减少模型维护的工作量、保证用例模型的可维护性和一致性,可以在用例之间抽象出包含(Include)、扩展(Extend)和泛华(Generalization)这几种关系。
(1)包含(Include)
包含关系指用例可以简单地包含其他用例具有的行为,并把它所包含的用例行为作为自身行为的一部分。
箭头由基础用例(Base)指向被包含用例(Inclusion),如图5:
包含关系代表基础用例会用到被包含用例,具体的讲就是将被包含用例的事件流插入到基础用例的事件流中。
图5
例子:图6
在处理包含关系时,具体的做法就是把几个用例的公共部分单独地抽象出来成为一个新的用例。主要有两种情况需要用到包含关系:
#多个用例用到同一段的行为,则可以把这段共同的行为单独抽象成为一个用例,然后让其他用例来包含这一用例。
#某一个用例的功能过多、事件流过于复杂时也可以把某一段事件流抽象成为一个被包含的用例,以达到简化描述的目的。
(2)扩展(Extend)
在一定条件下,把新的行为加入到已有的用例中,获得的新用例称为扩展用例(Extension),原有的用例称为基础用例(Base),从扩展用例到基础用例的关系就是扩展关系。
一个基础用例可以拥有一个或者多个扩展用例,这些扩展关系用例可以一起使用。
需要注意的是,在扩展关系中是基础用例而不是扩展用例被当做例子使用。
如图7:
图7:
例子:图8
注意:扩展关系和包含关系的不同点:
#在扩展关系中,基础用例提供了一个或者多个插入点,扩展用例为这些插入点提供了需要插入的行为。而在包含关系中插入点只能有一个。
#基础用例的执行并不一定会涉及到扩展用例,扩展用例只有在满足一定条件下才会被执行。而在包含关系中,当基础用例执行后,被包含用例是一定会被执行的。
#即使没有扩展用例,扩展关系中的基础用例本身也是完整的,而对已包含关系,基础用例在没有被包含用例的情况下就是不完整的存在。
(3)泛华(Generalization)
图9:
例子:图10: