购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第3章
建立需求模型
——用况图

用户需求就是用户对所要开发的系统提出的各种要求和期望,其中包括系统的功能、性能、保密要求和交互方式等技术性要求以及成本、交付时间和资源使用限制等非技术性要求。对分析员而言,功能需求是分析阶段要考虑的核心部分。

要进行软件开发,首先要准确地描述用户需求中的功能需求,形成功能规格说明。按照以往的做法,可采用多种方式描述需求。例如,可使用流程图、伪码和Aris模型 [ 1 ] 描述需求,也可以使用自己定义的语言描述需求。当前的一种主流做法是使用用况图来描述系统需求。

用况图用于对系统的功能以及与系统进行交互的外部事物建模。通过找出与系统交互的外部事物,并说明它们如何与系统交互,易于对系统进行探讨和理解。这样,用户能够理解未来的系统,开发者也能够正确地理解需求并实现系统。所产生的用况图是对所捕获的需求的规范化描述 ,是进行OOA的基础。对OOD阶段的人机交互设计和系统测试来说,用况也是非常重要的。

在建立需求模型时,先要确定系统边界,找出在系统边界以外与系统交互的事物,然后从这些事物与系统进行交互的角度,通过用况来描述这些事物怎样使用系统,以及系统向它们提供什么功能。

3.1 系统边界

在系统尚未存在时,如何描绘用户需要一个什么样的系统?如何规范地定义用户需求?

我们可以首先把系统看作一个黑箱,看它对外部的现实世界发挥什么作用,描述它的外部可见的行为。这里所说的系统是指被开发的计算机软件系统,而不是泛指问题域中的全部事物所构成的现实系统。用OO方法所开发的系统是通过对现实世界的抽象而产生的。问题域中的某些事物(如使用系统的一些人员)位于系统边界之外,作为系统的外部实体处理,而系统内的成分(简称系统成分)是指在OOA和OOD中定义的那些系统元素。

系统边界是一个系统所包含的所有系统成分与系统以外各种事物的分界线。如图3-1所示,系统是由一条边界包围起来的未知空间,系统只通过边界上的有限个接口与外部的系统使用者(人员、设备或外系统)进行交互。

把系统内外的交互情况描述清楚了,就确切地定义了系统的功能需求。若最终实现的系统就具有这样的功能,那这个系统也就是用户所需要的,即用户就是通过这样的交互使用系统。

现实世界中的事物与系统的关系包括如下几种情况:

图3-1 系统的使用者、系统边界和系统

1)某些事物位于系统边界内,作为系统成分。如超市中的商品,抽象为超市商品销售管理系统内的类“商品”。

2)某些事物将是与系统进行交互的参与者,系统中没有相应的成分作为它们的抽象表示,它们位于系统边界以外。如商场中的收款员,可以作为位于系统边界外与系统进行交互的参与者(若系统内设置了“收款机”对象),而不在系统中设立相应的“收款员”对象,这意味着系统并不关注收款员本身的信息和功能,而只关注销售与收款。

3)某些事物可能既有一个对象作为其抽象描述,而本身(作为现实世界中的事物)又在系统边界以外与系统进行交互。还是以超市中的收款员为例,他本身是现实中的人,作为系统的使用者;在系统边界内,又可有一个相应的“收款员”对象来模拟其行为或管理其信息,作为系统成分。这种做法注重收款员本身的信息和功能。

4)某些事物即使属于问题域,也与系统责任没有什么关系。如超市中的保安员,在现实中与超市有关系,但与所开发的系统“超市商品销售管理系统”没有关系。这样的事物既不位于系统边界内,也与系统无关。

认识清楚了上述事物之间的关系,也就确定出了系统边界。

3.2 参与者

对于每个有意义的系统,都存在着一些与系统打交道的事物,这些事物为了某些目的而与系统进行交互。这些事物还能预料到系统的运行方式,为达到某种目的事物间也可能要通过系统进行协作。

3.2.1 概念与表示法

一个参与者(actor)定义了一组在功能上密切相关的角色,当一个事物与系统交互时,该事物要扮演这样的角色。

例如,超市里的每个具体的收款员的首要职责为收款,他还要负责检验购物篮中商品的数量以及验证顾客的信誉卡以给予优惠。这样,每个收款员就要扮演三种在功能上紧密相关的角色。把这组角色定义为一个参与者,对其命名为“收款员”。该参与者的一个实例就是扮演上述角色的一个具体人。这个具体的人,可能还扮演其他参与者(例如“商品供货员”)的角色,这说明一个系统的用户可以扮演不同的参与者中的角色。此外,一个参与者也可以由一组用户来扮演,如参与者“收款员”往往代表着一组具体的人。

一个参与者可以发出请求,要求系统提供服务;系统以某种方式对其做出响应,把响应的结果返回给该参与者或者给其他的参与者。系统也可以向参与者发出请求,参与者对此做出响应。为了完成某项功能,一组参与者和系统之间请求与响应的对话可能是复杂的。

尽管在模型中使用了参与者,但参与者实际上并不是系统的一部分,它们位于系统之外,是在系统之外的与系统进行交互的任何事物。

参与者的标准图符是一个“人型符号”,参与者的名字放在图符的下方,如图3-2所示。

如果一些参与者与系统的交互有一部分是相同的,这时不是显式地将相同的交互与每一个参与者相关联,而是引入包含这些共同的交互的一般参与者,并对这些参与者进行特殊化处理,特殊参与者从一般参与者中继承执行这些交互的能力,见图3-3。

图3-2 参与者“顾客”的表示法

图3-3 参与者之间继承关系示例

从特殊参与者到一般参与者之间的继承关系,意味着特殊参与者的实例能够同与一般参与者的实例进行交互的用况实例进行通信。

3.2.2 识别参与者

上节讲到,参与者是在系统之外与系统进行交互的任何事物。具体地讲,参与者分为三类:人员、外部系统或设备。下面讲述如何从这三个方面识别参与者。

(1)人员

从直接使用系统的人员中发现参与者。这里强调的是直接使用,而不是间接使用。这样的人可能要启动、维护和关闭系统,更多的可能是这样的人要从系统中获得什么信息或向系统提供什么信息。

特定的人在系统中可扮演不同参与者中的角色。例如,添加数据、使用数据及产生分析报告的那个人就扮演了三种不同的角色,这些角色可能要分别属于三种不同的参与者。再如,对于使用银行系统的一个具体的人来讲,他扮演的角色可为前台职员、经理或顾客等。

(2)外部系统

所有与本系统交互的外部系统都是参与者。相对于当前正在开发的系统而言,外部系统可以是其他子系统、下级系统或上级系统,即任何与它进行协作的系统,但对这样的系统的开发并不是开发本系统的人员的责任,无论它们是已存在的,还是正在开发的。

要指出的是,如果一个大系统在任务分解时被划分成几个子系统,则每个子系统的开发者都把与之相关的其他子系统看作是外部系统,子系统的边界以内只包括它的开发者所负责的那部分功能。

(3)设备

识别如下的所有与系统交互的设备:这样的设备与系统相连,向系统提供外界信息;也可能系统要向设备提供信息,设备在系统的控制下运行。这样的设备是系统的参与者。通常,像监视器、键盘、鼠标这样的标准用户接口设备(操作系统管理它们)不包括在内,而像外部传感器和受控马达这样的与系统交互的设备很可能是参与者,因为所开发的系统往往要直接对它们进行处理。

下面是一些识别与组织参与者的指导策略:

1)首先将精力集中于启动系统的参与者。这些是最容易识别的参与者,从中可以找出其他参与者。

2)从用户的角度考虑怎样使用这个系统,从设备和外部系统的角度考虑它们如何与系统交互。

3)对识别出来的参与者,记录它们的责任。

4)通过识别继承关系,组织参与者。

5)若有必要,在参与者间建立继承关系。

3.3 用况

本节要讲述用况的含义、用况与参与者之间的关系、用况间的关系以及如何使用它们描述系统功能。

3.3.1 概念与表示法

一个用况(use case)是描述系统的一项功能的一组动作序列,这样的动作序列表示参与者与系统间的交互,系统执行该动作序列要为参与者产生结果。

把用况表示成一个包含用况名字的椭圆,见图3-4。

图3-4 用况的表示法

除了用图符表示用况外,对用况还要描述其活动序列。对用况的描述,可使用自然语言、活动图(见5.3节)和伪码,也可以使用用户自己定义的语言。无论用什么形式,所描述的动作序列都应该足够清晰,使得其他人员易于理解。书写动作序列时,应该反映出用况何时开始和结束,参与者何时与用况交互,交换什么内容,以及用况中的基本动作序列和可选动作序列等。

以超市销售管理系统为例,图3-5给出了实现系统收款功能的用况“收款”的描述。

图3-5 用况“收款”的描述

图3-5 (续)

上面的示例描述的是通常的收款情况,对于用信用卡付款和给予优惠等的描述可使用3.3.3节中讲述的用况之间的关系。

图3-5中,采用缩进文字的方式描述系统的行为,使得参与者与系统的行为容易区分。

还有一种常见的描述用况的方式,即区分用况的交互序列的基本流和可选流。例如,在一个图书馆借书系统中,有一个用况为“确认图书证”。其基本动作序列(基本流)为:工作人员可以用扫描仪识别借书证,也可以用键盘输入借书证信息;随后系统检查输入的数据是否合法;如果合法,系统显示该客户的借书情况。可选的动作序列(可选流)有多个:例如,1)如果输入的数据不合法,系统就要求重新输入;2)如果该用户借书过多,则停止他再借书。

有的做法是把基本动作序列和可选的动作序列分开来写。下面以ATM系统为例,采用基本流和可选流的方式,给出实现验证用户功能的用况“验证用户”的描述,见图3-6。

图3-6 用况“验证用户”的描述

在运用用况时要注意以下几点:

1)用况是一种类型,它是要被实例化执行的。当参与者实例使用由一个用况描述的一项系统功能时,该用况所描述的功能的全部或部分才发挥作用,其中经历的动作序列是该用况的一个实例,即一个场景(scenario)。

2)用况描述中的一个动作应该描述参与者或系统要完成的一个交互步骤。

3)执行用况的一个动作序列要为参与者产生可观察的结果,是指系统对参与者的动作要做出响应。例如,参与者向系统发一个命令,要求它做某件事;系统经过判断,要求参与者提供进一步的信息;参与者输入信息;系统进行处理,把结果报告给参与者。

4)用况描述的是参与者所使用的一项系统功能,该项功能应该相对完整,即应该保证用况是某一项功能的完整说明,而不能只是其中的一个片段。这就要求一个用况描述的功能,既不能过大以至于包含过多的内容,也不能过小以至于仅包含完成一项功能的几个小步骤。特别是,不能因为用况的功能过大,就像结构化分析方法把大的加工细分成下层的若干较小的加工那样,把用况也细分成下层的若干较小的用况,因为用况是不分层的,不能说上层的用况是由下层的较小用况组成的。

5)对用况的描述只强调用用况描述参与者和系统彼此为对方直接地做了些什么事,不描述怎么做,也不描述间接地做了些什么。例如,对于一个成绩管理系统的“成绩统计”功能,可以在某个用况中做这样的描述:“指定专业和年级,计算每个学生的各科成绩,并以成绩的高低为序打印成绩表。”该功能包含很多计算细节,如要进行数据检索、计算和排序等,但是这些细节并不在用况中描述。实际上,定义用况是在捕获需求,此时分析员还没有完全了解系统,还不能确定应该设立哪些成分以及成分之间的行为依赖关系,他们只能从系统的最高层次(即最接近参与者的层次)来观察和描述系统功能。对于参与者也只描述它对系统的直接动作(例如“输入某某数据”),不描述为了完成这个动作所进行的准备工作(例如为获得输入数据进行的调查、统计和计算)。

6)使用用况来可视化、详述、构造和文档化所希望的系统行为。尽管用况中描述的行为是系统级的,但在用况内所描述的交互中的动作应该是详细的,准则是对用况的理解不产生歧义即可。若描述得过于综合,则不易认识清楚系统的功能。

7)在用况描述中,由参与者首先发起交互的可能性较大,但有些交互也可能是由系统首先发起的。例如,系统在发现某些异常情况时主动要求操作员干预,或者系统主动地向设备发出操作指令。对于这样的情况,参与者和系统之间的交互就是由系统首先发起的。

8)在描述一个用况时,要求用况应该描述出可能出现的各种情况,并进行概括,不要顾此失彼;描述应力求准确、清晰,但不要把双方的行为混在一起。

3.3.2 用况与参与者之间的关系

一个参与者可以使用系统的多项功能,系统的一项功能也可以供多个参与者使用。在用况图中,体现为一个参与者可以同多个用况交互,一个用况也可以同多个参与者交互。对于前一种情况,参与者根据与其交互的各用况分别扮演了不同的角色。

在UML中,把参与者与用况间的这种交互关系称为关联。若没做具体的规定,交互是双向的,即参与者能够对系统进行请求,系统也能够要求参与者采取某些动作。

把参与者和用况之间的关联表示成参与者和用况之间的一条实线。若要明确地指出参与者和用况之间的通信是单向的,就在接收通信的那端的关联线上加一个箭头,用以指示方向。图3-7给出了一个参与者和用况之间的关联示例。

图3-7 参与者和用况之间的关联示例

图3-7中的参与者“收款员”分别与用况“收款”和“检查商品”间存在着关联,参与者“统计员”与用况“收款”间存在着关联。这意味着“收款员”的实例与“收款”和“检查商品”的实例进行交互,“统计员”的实例与“收款”的实例进行交互。

3.3.3 用况之间的关系

不但在参与者和用况之间存在着关联关系,在用况之间也可存在一定的关系。例如,在下述情况下,就需要考虑产生新的用况,并在用况间建立关系:

·在一个用况中存在着几处重复使用的动作序列。

·在几个用况中存在着重复使用的动作序列。

·一个用况中的主要动作序列或分支动作序列过于冗长或复杂,而且分离它们有助于对需求进行管理和理解。

UML把用况之间存在的关系分为三种:包含、扩展和继承。

1. 包含

在一个或几个用况中经常存在着重复的交互行为。为了避免重复,可把重复的交互行为放在一个用况中,原有的用况(基用况)再引入该用况(供应者用况),这样就在用况间建立了包含关系(include relationship)。原来用况中剩下的部分通常是不完整的,依赖于被包含部分才有意义,即供应者用况是包含它的基用况的功能的一部分。进一步地讲,从基用况到供应者用况的包含关系表明:基用况在它内部说明的某一(些)位置上显式地使用供应者用况的行为的结果。

可以把包含关系想象为基用况调用供应者用况(类似于子程序调用),基用况仅仅依赖供应者用况执行的结果,而不依赖供应者用况内部的结构。

建立包含关系的方法很简单,即从具有共同活动序列的几个用况中抽取出公共动作序列,或者在一个用况中抽取重复出现的公共动作序列,形成一个在几处都要使用的附加用况。这样,可以避免多次描述同一动作序列;当这个共同的序列发生变化时,这样做就显现出优势,即只需要在一个地方改动即可。

用一个敞开的带箭头的虚线(简称为虚箭线)表示用况之间的包含关系,该虚箭线从基用况指向被包含的用况(供应者用况),并在虚箭线上用《include》标记,见图3-8。

图3-8 用况间的包含关系的表示法

具有包含关系的用况间并不一定是一对一的。实际上,一个用况可以包含多个用况,一个用况也可以被多个用况包含,甚至一个供应者用况还可以包含其他用况。

2. 扩展

在一个或几个用况的描述中,有时存在着可选的描述交互行为的片段。在这种情况下,可以从用况中把可选的交互行为描述部分抽取出来,放在另一个用况(扩展用况)中,原来的用况(基用况)再用其进行扩展,以此来解决候选路径的复杂性。这样在描述基本动作序列的基用况和描述可选动作序列的扩展用况之间就建立了扩展关系(extend relationship)。进一步地讲,从基用况到扩展用况的扩展关系表明:按基用况中指定的扩展条件,把扩展用况的动作序列插入到由基用况中的扩展点定义的位置。

基用况是可单独存在的,但是在一定的条件下,它的行为可以被另一个用况的行为扩展。扩展用况定义一组行为增量,扩展用况定义的行为离开基用况可能是无意义的。注意,扩展用况中定义的各行为增量是可以单独插入到基用况中的,这与包括关系中的供应者用况要作为一个整体被包含是不同的。

用虚箭线表示用况之间的扩展关系。该箭头从扩展用况指向基用况(方向与包含关系相反),并用《extend》标记虚箭线,还可在《extend》附近写上扩展条件,见图3-9。

图3-9 用况间的扩展关系的表示法

一个扩展点是用况中的一个位置,在这样的位置上,如果扩展条件为真,就要插入扩展用况中描述的全部动作序列或其中的一部分,并予以执行。执行完后,基用况继续执行扩展点下面的行为。如果扩展条件为假,扩展不会发生。

在一个用况中,各扩展点的名字是唯一的。可以把扩展点列在用况中的一个题头为“扩展点”的分栏中,并以一种适当的方式(通常采用普通的文本)给出扩展点的描述(作为基用况中的标号)。图3-10给出了一个示例。

图3-10 扩展点的表示法示例

在图3-10中,用况“使用ATM”有一个扩展点“帮助”。当用况“使用ATM”的实例执行到达扩展点“帮助”所标识的位置,且用户选择了帮助(即扩展条件{用户选择了“帮助”}为真)时,该用况就借助这个扩展点用用况“联机帮助”来扩展自己。图中的带虚线的折角矩形用于表示注释。

一个扩展用况可以扩展多个基用况,一个基用况也可以被多个用况扩展,甚至一个扩展用况自身也可以被其他扩展用况来扩展。

若要在基用况中表述可选的交互行为,就可以使用扩展关系。用这种方式把可选行为分离出来,通过扩展关系在扩展点使用它们。在对例外行为处理建模时或对系统的可配置的功能建模时,也可使用扩展关系。

3. 继承

用况之间的继承关系的含义如同类之间或参与者之间的继承关系一样。特殊用况不但继承一般用况的行为,还可以增加行为或覆盖一般用况的行为。一般用况和特殊用况均有具体的实例,特殊用况的实例可以出现在一般用况的实例出现的任何位置。

用一个指向一般用况的带有封闭的空心箭头的实线来表示用况之间的继承关系,见图3-11。

在本小节的最后要强调的是,尽管用况间的三种关系都有助于复用,但从上面的讲述中可以看出,它们之间是有区别的。

图3-11 用况间的继承关系的表示法

3.3.4 捕获用况

可以从如下几个方面来捕获用况。

1. 从参与者的角度捕获用况

用况用于描述参与者和系统之间的一系列交互。参与者 通常作为交互的发起者,使用系统来完成某种任务。识别参与者的责任是寻找参与者与系统交互理由的良好基础。对所有的参与者,提出下列问题:

·每个参与者的主要任务是什么?

·是什么事件引发了任务,从而开始了参与者与系统进行交互?

·在交互过程中,参与者是怎样使用系统的服务来完成它们的任务的?例如,参与者是否将读、写或删除系统的什么信息?参与者是否该把系统外部的变化通知给系统?参与者是否希望系统把内部的变化通知给自己?参与者是否希望系统把预料之外的变化通知自己?

·参与者参加了什么本质上不同的交互过程?有些交互过程实际上是相同的或相似的,如果出现这些情况,需要合并用况或在用况间建立前述关系。

能完成特定功能的每一项活动明确地是一个用况。这些参与者参与的活动,通常会导致其他活动,进而可识别出其他用况。

2. 从系统功能的角度捕获用况

欲达到某种目的的一组动作序列要完成一项功能,这样的动作序列要描述在一个用况中。通常,以用况中的交互动作为线索能发现其他用况。如下是一些指导:

·全面地认识和定义每一个用况,要点是以穷举的方式考虑每一个参与者与系统的交互情况,看看每个参与者要求系统提供什么功能,以及参与者的每一项输入信息将要求系统做出什么反应,进行什么处理。

·以穷举的方式检查系统的功能需求是否能在各个用况中体现出来。

·一个用况描述一项功能,但这项功能不能过大。例如,把一个企业管理信息系统粗略分为生产管理、供销管理、财务管理和人事管理等几大方面的功能,并分别把它们各作为一个用况,粒度就太大了。对于这种情况,应该把系统先划分成子系统(见14.1节),再针对子系统建立用况模型。

·一个用况应该完成一项完整的任务,通常应该在一个相对短的时间段内完成。如果一个用况的各部分被分配在不同的时间段,尤其还被不同的参与者执行,最好还是将各部分作为单独的用况对待。

·针对用况描述的基本流,要详尽地考虑各种其他的情况。

·考虑对例外情况的处理。

3. 利用场景捕获用况

如果不能顺利地确定一个用况的描述,可尽早使用人们熟知的“角色扮演”技术。该技术要求建模人员深入到现场,通过观察业务人员的现场工作(就好像自己是业务人员一样),深入地理解业务人员的工作,将具体的工作流程记录下来,形成一个用来说明完成特定功能的动作序列,即一个场景。一个场景应该仅关注一次具体的业务活动,尽量要详细。要确定出谁是扮演者,他们做了什么事,他们做这些事的用意是什么,或者是什么原因要求他们做这些事。在描述一个场景时,还要指出其前驱和后继场景,并要考虑可能发生的错误以及对错误的处理措施。通过建模人员的角色扮演活动,找出各具体的场景;然后再把本质上相同的场景抽象为一个用况,如图3-12所示。

图3-12 用况是对多个场景的抽象

从另一个方面看,用况的一次执行也形成了一个场景。用况的一次执行所经历的动作序列可能为用况描述中的一部分。例如,在图3-5所示的例子中,若某顾客在一次购物中购买的商品只是一件,就不执行“输入商品数量”这个动作,也不需要多次执行for循环的循环体。

通过从上述三个方面捕获到的用况,有些是简单的,只有一个动作序列,有些要复杂一些,具有一些可选择的交互路径和多种例外的情况。一般而言,用况中含有一个在通常的情况下发生的基本动作序列,其余的为可选的动作序列。

3.3.5 用况模板

对于所捕获的用况,需要按一定的格式对其进行描述,形成用况规约。按照国家电子信息行业标准《面向对象的软件系统建模规范第三部分:文档编制》 [ 14 ] 的要求,图3-13给出了用于描述用况的模板。

图3-13 用况模板

在描述用况时,并不要求把用况模板中的每一项都写出来,而是可以根据需要进行相应的取舍。根据用况图,功能良好的建模工具能够把参与者以及包含、扩展和继承关系中的用况提取到用况规约中。

3.4 用况图

用况图是一幅由参与者、用况以及这些元素之间的关系组成的图。这些关系是参与者和用况之间的关联、参与者之间的继承,以及用况之间的包含、扩展和继承。根据需要,用况图也可以有注释(见图3-15中的卷角矩形)。

可以选择把用况用一个矩形围起来,用来表示系统或子系统的边界。图3-14为一个订单处理系统的用况图。

在图3-14中,用大方框把用况围起来,而把参与者放在外边,以此来表示系统边界。也可以不画系统边界,因为参与者位于系统边界以外而用况位于系统边界以内本身就体现出了系统边界的含义。

图3-14 订单处理系统的用况图

图3-15所示的是一个银行取款系统的用况图片段。

图3-15 银行取款系统的用况图(片段)

图3-15中用到了用况间的两种关系。图3-16和图3-17给出了其中两个用况的文字描述片段。

图3-16 “处理存款单”用况的文字描述片段

图3-16中的包含与扩展的写法是建议性的,UML对此没有做出规定。

图3-17 用况“检查口令”的文字描述片段

图3-17所示用况的书写方式强调基本流和可选流。

图3-15所示的用况图仅是整个银行取款系统的用况模型中的一部分,只是说明了有限的功能。如果系统比较复杂,就要绘制多幅用况图,每幅用况图只注重于系统功能的一个方面。

使用用况图描述系统需求有如下益处:

1)由于系统可能会很复杂,分析员借助于用况模型可正确而全面地理解需求。

2)分析员能够得到的反映用户需求的材料常常是不够规范或不够准确的。通过全面、细致地定义用况,可把用户对系统的功能需求比较准确地在用况模型中表达出来,并且在形式上是较为规范的。

3)为领域专家、用户和开发者提供一种相互交流的手段,以使各方对需求的理解达成共识。

4)用况可以作为人机界面的设计基础,也可用做黑盒测试的测试用例。

3.5 检查与调整

对于各用况图应该综合考虑,进行检查与调整。下面针对参与者和用况给出一些需要注意的检查与调整原则。

1. 参与者

1)确定系统环境中的所有角色,并都归入了相应的参与者。

2)每个参与者都至少与一个用况相关联。

3)若一个参与者是另一个参与者的一部分,或扮演了类似的角色,考虑把它们合并或在它们之间建立继承关系。

2. 用况

1)每个用况都至少与一个参与者相关联。

2)若两个用况有相同或相似的序列,可能需要合并它们,或抽取出一个新用况,在它们之间建立包含、扩展或继承关系。

3)若用况过于复杂,为了易于理解和开发,考虑进行分解;若一个用况中有着完全不相关的动作序列,最好把它分解成不同的用况。

在对系统的功能需求进行捕获和描述时,还需要注意以下几点:

1)对所有用况的描述应该尽可能完整、准确。

2)在后续的开发过程中,很可能发现需求有了新的变化,或发现原先的理解有偏差,这时有必要修改已有的用况模型,以保证系统模型的正确性和一致性。

3)在用用况描述需求时,讲的是系统做什么,而不是如何做。也就是说,仅描述系统内外交互的情况,不应该包含系统内部的实现信息。若使用第5章要讲述的活动图描述用况,注意不要描述系统的内部功能。

4)用况的大小要适中,原则是不但要捕获需求,还要便于实施后续的分析、设计与测试。若发现用况过大,就要通过进一步的分析对它进行分解。若发现用况过小,就要考虑是否把它作为其他用况的一部分。

5)用况描述的是系统内外交互的情况,但不能按人机界面来建立用况图,而应该按功能来描述系统内外的交互。注意,界面不是用况,用况也不是界面,一个用况可能包含所要建造的系统的多个界面,一个界面也可能由多个用况使用。

6)尽量不要使用多层的包含、扩展或继承关系,因为这样做有可能要走上功能分解的道路。

本书强调以用况图为基础,针对问题域和系统责任进行面向对象的分析和设计,而没有进一步说明以用况为驱动的开发方法。若要使用这样的方法,就要充分考虑开发各用况的优先级和风险,并要对用况做高层与低层、主要与次要、本质与具体的区分 [ 6 ]

3.6 用况模型与OOA模型

在本书中用况模型是OOA模型的一部分,是进一步实施OOA的基础,具体内容如图3-18所示。

图3-18 用况模型与OOA模型的关系

3.7 例题

很多软件系统在一开始都需要登录,若用户登录成功,则可进入系统。如下以一个研究生学籍管理系统为例,描述四种登录方案。

出于简化和能够说明与解决问题起见,此处仅描述了登录、选课和查看学分这三项功能。

1. 方案一

由于选课和查看学分都需要登录,故专门设立一个“登录”用况。若登录成功,则可以进行选课,也可以查看学分,见图3-19。

图3-19 方案一的用况图

如下为对用况“登录”的描述:

该方案的缺点是,必须要了解系统的其他模块才能描述清楚用况“登录”。向系统增减功能时,也要修改用况“登录”。从维护的角度看,可能会忘记对用况“登录”进行修改。

从概念上讲,选课与查看学分并不是登录的组成部分,用况“登录”的文字描述中的后半部分实际上是与登录无关的。这表明,该用况的功能不单一。

2. 方案二

用用况“选课”和“查看学分”扩展用况“登录”,见图3-20。

图3-20 方案二的用况图

如下为对用况“登录”的描述:

该方案与方案一相比,除了在图上对“登录”用况的描述要清楚一些外,仍未解决方案一中存在的问题。

3. 方案三

让所有的相关用况都包含用况“登录”,见图3-21。

图3-21 方案三的用况图

如下为对用况“登录”的描述:

如下为对用况“选课”的简化描述:

如下为对用况“查看学分”的简化描述:

这个方案中的用况“登录”仅描述有关登录的信息。研究生执行系统的其他功能都要先登录,这导致该方案有缺点:研究生可能要进行多次登录,且用况“登录”和“选课”的功能不单一。

4. 方案四

用况“登录”完全独立于其他用况,见图3-22。

对用况“登录”的描述同方案三。如下为对用况“选课”的简化描述:

图3-22 方案四的用况图

对用况“查看学分”的描述也与此类似。

若使用该方案,必须要在用况“选课”和“查看学分”中指定前置条件:只有在登录成功后才能执行自己的其他交互。该方案较为简洁,但在图上不能直接看出用况之间的关系。

习题

1. 用况之间的关系可为包含关系、扩展关系或继承关系,三种关系之间有相同之处吗?它们之间的区别又在哪里?

2. 论述用况图在面向对象方法中的地位。

3. 怎样理解把系统内外的交互情况描述清楚了,就明确了系统边界?

4. 对于3.3.1节中的收款用况,补充使用信用卡付款和使用优惠卡的描述。

5. 自动售货机会按用户的要求进行自动售货,供货员会巡查向其内供货,取款员会定时取款。针对上述要求,请建立用况图,并描述各个用况。

6. 现要开发一个购书积分系统,其中至少要具有申请积分卡、增加积分、查看积分和按积分奖励功能。请建立用况图,并描述各个用况。 yquk619PrhP89mLoGafltGz6Hp7ddvMnndtIJHBujXbeSZThoTqfFgwrNSMlEPyH

点击中间区域
呼出菜单
上一章
目录
下一章
×