返回列表 回复 发帖

[SPOTO推荐]UML轻松入门——用例

UML轻松入门——用例

1 用例与用例图

  用例是需求分析中最重要的概念,需求表征了一个系统的设计特性、特征和行为,描述一个系统的需求意味着描述了建立在该系统外部的事物与系统之间的契约,契约上声明了期望系统做什么。

  需求获取(Requirement Elicitation) 是需求工程的主体,其主要工作是建立待开发系统的模型,而用例就是用于建立这种模型的良好方法。用例最初由Ivar Jackboson博士提出,后被综合到UML规范之中,成为需求表述的标准化体系。前文已经提到,整个RUP流程都是"用例驱动"的,各种类型的开发活动包括项目管理、分析、设计、测试、实现等以用例为主要输入工件,用例模型奠定了整个系统软件开发的基础,用例被认作第二代面向对象技术的标志,可见其重要性非同一般。

  我们先来给出一个具体而简单的用例图,即"图书管理系统"用例图,如图1。在用例图中主要涉及到参与者(又称角色、执行者)、用例以及二者之间的通讯关联。


图1 图书管理系统用例图

  参与者

  参与者是与系统、子系统或类发生交互的外部用户、进程或其他系统。参与者可以是人、另一个计算机系统或一些可运行的进程。在图1中,"读者"和"管理员"即为参与者。

  参与者之间可以存在泛化关系,例如,在图1所示图书馆管理系统用例图中,可以认为"读者"是"学生读者"和"教师读者"的泛化,而"学生读者"还可以具体化为"本科生读者"和"研究生读者";同样,"图书管理人员"也是"采购员"、"编目员"及"借阅人员"的泛化。图2表示出了参与者之间的泛化关系。


图2 参与者泛化关系

  用例

  用例是外部可见的一个系统功能,这些功能由系统所提供,并通过与参与者之间消息的交换来表达。用例的用途是在不揭示系统内部构造的情况下定义行为序列,它把系统当作一个黑箱,表达整个系统对外部用户可见的行为。

  鉴于用例的特点,用例一般被命名为一个能够说明目标的动名词组。如图1中的"借书"、"还书"和"管理图书"皆为动名词组。

  用例之间也可以存在包含、扩展和泛化等关系:

  (1)包含关系:用例可以简单地包含其他用例具有的行为,并把它所包含的用例行为做为自身行为的一部分,这被称作包含关系。

  (2)扩展关系:扩展关系是从扩展用例到基本用例的关系,它说明为扩展用例定义的行为如何插入到为基本用例定义的行为中。它是以隐含形式插入的,也就是说,扩展用例并不在基本用例中显示。在以下几种情况下,可使用扩展用例:

  a.表明用例的某一部分是可选的系统行为(这样,您就可以将模型中的可选行为和必选行为分开);

  b.表明只在特定条件(如例外条件)下才执行的分支流;

  c.表明可能有一组行为段,其中的一个或多个段可以在基本用例中的扩展点处插入。所插入的行为段和插入的顺序取决于在执行基本用例时与主角进行的交互。

  图3给出了一个扩展关系的例子,在还书的过程中,只有在例外条件(读者遗失书籍)的情况下,才会执行赔偿遗失书籍的分支流。

图3用例扩展关系

  (3)泛化关系:用例可以被特别列举为一个或多个子用例,这被称做用例泛化。当父用例能够被使用时,任何子用例也可以被使用。如在图4中,管理图书是添加图书和修改图书信息的抽象。


图4用例泛化关系

  通讯关联

  通讯关联用于表示参与者和用例之间的对应关系,它表示参与者使用了系统中的哪些用例(或者说系统所提供的用例被哪些参与者使用)。

  通讯关联以箭头或实线表示。若使用箭头,箭头所指方将是对话的被动接受者;如果不强调对话中的主动与被动关系,则可以使用不带箭头的关联实线。

  2建立用例模型

  知道了用例与用例图的概念,我们还需要懂得怎样建立用例模型,即怎样找出参与者、用例以及定义用例的过程。一般来说,建立用例模型的步骤为:

  (1)确定谁会直接使用该系统,即参与者(Actor),为了发现参与者,我们可以尝试问如下问题:

  a. 谁/什么使用系统?

  b. 谁/什么从系统获得信息?

  c. 谁/什么向系统提供信息?

  d. 谁/什么支持、维护系统?

  e. 哪些其它系统使用此系统?

  f. 公司的哪个部门使用系统?

  …

  (2)选取其中一个参与者;

  (3)定义该参与者希望系统做什么,参与者希望系统做的每件事成为一个用例,为了发现用例,我们可以尝试问如下问题:

  a. 为什么该参与者想要使用此系统?
UML轻松入门--综合实例

ATM(自动取款机)现在在城市的大街小巷随处可见。我们在日常生活中也经常和ATM打交道。本章我们将以简化的ATM系统为例将前面几章中学到的用例图、类图、顺序图、状态图、活动图及协作图知识运用到此例中。

1 用例图

  参与者"银行储户"和ATM机。简化后的ATM机仅有取款、存款及其余功能。其余功能不做详细说明。

  银行储户在ATM机上完成取款、存款及其他业务。

  2 类图

  图2所示的银行系统类图和图5是类似的,只是将工作人员换成了ATM。整个银行系统包括了帐户库、银行储户库及ATM系统。

  许多单个的帐户组成了帐户库。帐户具有帐户类型、帐户号、余额三个属性,均为private,其类型分别为char,int,double。六个操作分别为setType、getType、getAccountNumbe、setAccountNumbe、caculateBalance、getBalance,除caculateBalance为protected其余均为public。

   setType设置帐户类型,返回类型为void,参数类型为char,输入帐户类型。

   getType获取帐户类型,返回类型为char,无参数。

   setAccountNumbe设置帐户号,返回类型为void,参数类型为int,输入帐户号。

   getAccountNumbe获取帐户号,返回类型为int,无参数。

   caculateBalance计算余额,返回类型为void,参数为double,第一个参数为输入存取款数额,第二个参数为存款余额,既为输入也为输出。

   getBalance获取帐户余额,返回类型为double,无参数。

  许多银行储户组成了储户库。ATM系统包含了许多ATM机。银行储户及ATM机两个类包含哪些属性,哪些操作,它们的可见性及操作的返回类型、参数个数、参数类型从类图上都一目了然。更多的属性及操作都可以一一加上,使这个类图更详细更完整,从而使参与项目的每个成员都能无歧义的明了整个设计的类的结构。同样对于一个真正的银行系统,这个类图过于简单。比如帐户类型我们可以先定义一个abstract class,它包含一个帐户最基本的属性及操作。而有些操作先定义为abstract,如余额的计算。然后再继承这个abstract class,我们可以有saving account 和checking account等等。不同的帐户有不同的余额计算方法,我们可以加上具体的算法。对于不同的帐户可能还有一些它特有的操作,我们也可以加上,比如saving account在存款达到多少时可以享受机票打折的优惠。通过类图不仅可以使设计者明确的表达自己的设计意图,也能帮组自己整理思路,充实及优化自己的设计。


图2 银行系统类图

  3 顺序图

  图5.3描述了顾客在ATM机上取款时信息的流动情况。以时间为顺序。因为仅是示例,所以整个过程是没有出现任何故障时的流程,并且只画到了取款结束。通过这个图,我们可以看出消息是如何在系统中不同对象之间进行交互。

  通过流程图我们可以很清楚地看到系统是如何工作的,系统各部分之间的信息及控制是如何发送的,整个流程是否合理。流程图对我们的设计起到了很好的帮助作用。注意在本图没有一个生命线终端有一个"X",这是因为这个流程中还未遇到有对象生命结束。当有对象生命结束时需在对应的生命线终端画"X",表明这个对象在这时被销毁。

  首先银行储户将ATM卡插入读卡机,读卡机将信息传给客户管理,客户管理提出查询密码,显示部分将输入密码请求显示出来…..因为这个顺序图较长,且很清晰,即便是初学者也很容易读懂,在此就不对本图做过多的解释。


图3 ATM取款顺序图


4 状态图

  图4描述了顾客在ATM机上进行操作会经历的几种状态,及各种状态之间转换的条件。因为是简化了的例子,所以除了等待顾客插入磁卡的起始状态和结束服务的终止状态,顾客会处于输入密码、选择服务类型、存款及取款四种状态。


图4 ATM状态图

  插入磁卡后进入输密码状态,当密码输入正确时进入选择服务类型状态,当输入密码不正确时,停留在原状态,但如果三次不正确,服务结束。进入选择服务类型后根据选择的不同,顾客可进入存款和取款状态。存、取款结束后,顾客既可以选择结束服务到最终状态,也可以选择继续服务回到选择服务类型状态。

  通过状态图我们可以无歧义的了解各个活动角色是如何在不同状况下转换的,转换的条件是什么,是否会出现死锁现象,是否有条件没考虑周全,是否有状态无法达到。状态图可以帮助我们发现问题,并及时改正。

  5 活动图

  图5参考了Randy Miller的《A Hands-On Introduction for Developers》一文,3图中的客户管理和事物管理对应于5图中的Bank,图3中的读卡机、显示、输入设备及点钞机对应于5图中的ATM Machina,银行储户就是Customer。初看活动图和顺序图表达的意义很接近。但我们可以注意到顺序图着重时间的顺序,而活动图侧重于各部分之间的相互制约,对于一些并行的活动能够有效的表示出来。例如5图中fork和join处,我们可以很清楚的看到一些并行活动的存在。

 
UML轻松入门--动态建模

  静可描形,动可描行。动和静是辩证的两面,在UML中,静态建模可以描述系统的组织和结构,而动态建模则可描述系统的行为和动作。

  前一节中介绍的类图和对象图主要用于静态建模,本节我们将描述UML中的动态建模机制。在动态建模机制中,以消息来完成对象之间的交互,用状态图、顺序图、协作图和活动图来描述系统的行为。


  1消息

  在面向对象领域,两个对象的交互是通过消息的发送和接收来完成的。消息分为简单消息、同步消息和异步消息:

  (1)简单消息:只是表示控制如何从一个对象发给另一个对象,并不包含控制的细节;

  (2)同步消息:同步意味着阻塞和等待,如果对象A给对象B发送一个消息,对象A会等待对象B执行完这个消息,接着才进行自身的工作;

  (3)异步消息:异步意味着非阻塞,如果对象A给对象B发送一个消息,对象A不必等待对象B执行完这个消息,就可以接着进行自身的工作。

  2顺序图

  顺序图(也称序列图)是一种交互图(Interaction Diagram,用于描述执行系统功能的各个角色之间相互传递消息的顺序关系,显示跨越多个对象的系统控制流程),强调的是时间和消息的次序,用来说明系统的动态情况,顺序图由参与者、对象、对象生命线和消息组成。一个顺序图显示了一系列的对象(通常是类的实例,也可以代表其他事物的实例,例如协作、组件和节点)和在这些对象之间发送和接收的消息。


图1 图书入库顺序图

  图书管理系统中图书入库的顺序图如图4.1所示,对于顺序图,往往在文字表述上会出现"当…时…"、"首先"、"然后"、"接着"、"…发出…消息","…响应…消息"等词汇。例如图1的顺序图可用文字表达为:

  当管理人员把新书入库时,首先要求登录(输入用户名和口令),经系统的"注册表单"验证,若正确无误,则可继续下一步交互,否则拒绝该管理人员进入系统。若登录正确,管理人员可发出查询请求消息,系统的"图书入库表单"对象响应请求。若管理人员发出增加或删除库存图书请求,"库存图书"对象将响应该消息,找出数据库中的相关数据并执行相应的操作。此后,管理人员应按下提交键确认请求,"图书入库表单"接口对象应该响应该请求,并发出存储消息,才由"库存图书"对象响应存储消息,进行数据库存储操作。如果管理人员结束图书入库,发出退出系统的请求,则系统的"注册表单"接口对象响应请求,关闭系统。

  3状态图

  状态图是UML中的状态机视图。状态机由对象的各个状态和连接这些状态的转换组成。每个状态对一个对象在其生命期中满足某种条件的一个时间段建模,当一个事件发生时,它会触发状态间的转换,导致对象从一种状态转化到另一新的状态。与转换相关的活动执行时,转换也同时发生。

  状态图用于描述对象可以拥有的状态以及引起状态相互转移的事件和条件,它揭示了对象的生命周期,是针对类的一种建模工具。状态是对象前一次操作的结果,事件是引起状态向另一状态转化的活动。所有对象都有状态,但通常只对具有复杂行为的类建立状态图。状态图强调的是事件驱动的对象的动作,这在对反应式系统的建模是相当重要的。

  两个类的状态图之间可以相互发送消息,一个状态还可以有嵌套的子状态,各子状态之间的关系可以为与/或关系。

  例如车载GPS终端系统中,车载GPS终端一方面与GPS卫星通信,另一方面将从GPS卫星获得的位置信息(经度、维度等)通过GSM短消息与车辆监控调度中心进行交互。

  在这样的系统中,鉴于通信过程中GPS终端可能处于不同的状态,我们可用状态图来对其进行描述,这样很直观和明确。图2给出了GPS终端的状态(待命、有问题、通话中、短消息通讯中)及其状态之间的变迁关系。


图2 GPS终端的状态图

  4 活动图

  活动图用于描述系统、用例、程序模块中的逻辑流程的先后执行次序、并行次序,是对人类组织的现实世界中的工作流程的建模,有助于理解系统高层活动的执行行为。

  活动图中的主要概念是"活动",而"活动"的具体含义又取决于作图目的和抽象层次:

  (1)当活动图用于描述系统行为时,主要侧重于系统多个用例活动之间相互制约的执行顺序,同时,识别出系统中存在的可以并行进行的用例,此时,活动表示系统要完成的任务;

  (2)当活动图用于描述用例时,用于描述用例中的操作执行次序和操作完成的结果,显示多个对象的操作是如何相互结合起来共同完成用例的一个脚本,揭示出操作之间的并行性,为编码实现提供开发并行程序的便利,此时,活动表示类中的方法,即操作。允许将某个组织或执行者要完成的若干操作聚集在泳道中,以明确责任。

 
返回列表