用例的本质及用例图

本文详细解析了UML中的用例概念,介绍了用例的发展历程和技术特点,探讨了用例的本质及其与系统需求的关系,并提供了实用的用例建模技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

提到UML中的用例,很多人可能都会觉得很熟悉经常听说。如果问一句什么是用例,很多的回答就是用例图中的一个椭圆。用例仅仅是用例图中的一个椭圆吗?当然不是,那么用例的本质是什么呢?

1、用例发展史

  为了搞清用例的本质我们首先了解一下用例技术的发展史。UML中的用例概念是由有UML之父Ivar Jacobson在60年代提出。后来Alistair Cockburn从Ivar Jacobson那里学习了用例,并且结合自己的实践对用例进行了继承和发展,提出了“基于目标的用例”。在UML形成的时候,用例UML作为一个重要的部分被纳入了UML。用例被认为是第二代面向对象技术的标志。 用例图中包含的元素除了系统边界、角色和用例,另外就是关系。关系包括用例之间的关系,角色之间的关系,用例和角色之间的关系。

1、角色之间的关系:

  角色之间的关系。由于角色实质上也是类,所以它拥有与类相同的关系描述,即角色之间存在泛化关系,泛化关系的含义是把某些角色的共同行为提取出来表示为通用的行为。

2、用例之间的关系:

  包含关系:基本用例的行为包含了另一个用例的行为。基本用例描述在多个用例中都有的公共行为。包含关系本质上是比较特殊的依赖关系。它比一般的依赖关系多了一些语义。在包含关系中箭头的方向是从基本用例到包含用例。在UML1.1中用例之间是使用和扩展这两种关系,这两种关系都是泛化关系的版型。在UML1.3以后的版本中用例之间是包含和扩展这两种关系。

  泛化关系:代表一般于特殊的关系。它的意思和面向对象程序设计中的继承的概念是类似的。不同的是继承使用在实施阶段,泛化使用在分析、设计阶段。在泛化关系中子用例继承了父用例的行为和含义,子用例也可以增加新的行为和含义或者覆盖父用例中的行为和含义。

  扩展关系的基本含义和泛化关系类似,但在扩展关系中,对于扩展用例有更多的规则限制,基本用例必须声明扩展点,而扩展用例只能在扩展点上增加新的行为和含义。与包含关系一样,扩展关系也是依赖关系的版型。在扩展关系中,箭头的方向是从扩展用例到基本用例,这与包含关系是不同的。

   用例的泛化、包含、扩展关系的比较。一般来说可以使用“is a”和“has a”来判断使用那种关系。 范化和扩展关系表示用例之间是“is a”关系,包含关系表示用例之间是“has a”关系。扩展与范化相比多了扩展点,扩展用例只能在基本用例的扩展点上进行扩展。在扩展关系中基本用例是独立存在。在包含关系中在执行基本用例的时候一定会执行包含用例。如果需要重复处理两个或多个用例时可以考虑使用包含关系,实现一个基本用例对另一个的引用。当处理正常行为的变形是偶尔描述时可以考虑只用泛化关系。当描述正常行为的变形希望采用更多的控制方式时,可以在基本用例中设置扩展点,使用扩展关系。扩展关系比较难理解,如果把扩展关系看作是带有更多规则限制的泛化关系,可以帮助理解。通常先获得基本用例,针对这个用例中的每一个行为提问:该步骤会出什么差错?该步骤有不同的情况吗?该步骤的工作怎样以不同的方式进行等,把所有的变化情况都标识为扩展。通常基本用例很容易构造,而扩展用例需要反复分析、验证。当我们发现已经存在的两个用例间具有某种相似性时,可以把相似的部分从两个用例中抽象出来单独作为一个用例,该用例被这两个用例同时使用,这个抽象出的用例和另外两个用例形成包含关系。

 3、验证模型:

  每个用例都需要明确的解决角色相关的问题,这个原则对于检查用例的合理性很有用。每个用例都必须至少有一个角色与之相关联,否则新增加一个角色,要么删除该用例。用例由一定的业务步骤组成,其中还会涉及业务的变化情况、出错情况,在用例中这些都需要包含,否则就不是一个完整的用例。

  用例图的最后检查:

  (1)是否所有的角色、用例都有相应的关联用例或关联角色

  (2)某些用例间是否有相似性,如果有引入包含关系

  (3)某些用例间是否有特殊情况,如果有引入扩展关系

4、用例的粒度:

  如果用例的粒度很大,得到的用例数就会很少,如果用例的粒度很小那么用例数就会很多。识别用例一方面要从系统的功能需要中抽象出用例,同时还要控制用例的数目。用例数目过多则造成用例模型过大,同时引入设计困难的可能性也加大了,用例数目过少则造成用例的粒度太大,不便于进一步分析,或者不充分。这个问题有很多人在争论。Ivar Jacobson认为一个10人年的项目,他需要大约20个用例。而在一个相同规模的项目中Martin Fowler则用例100多个用例。这个问题还需要设计人员根据自己的经验来综合考虑。

5、数据库的CURD设计:

  对于这样的问题通常有两种设计方式。比如在学生档案管理系统中,管理员要增加一条学生记录、修改一条学生记录、删除一条学生记录。方法一的设计是用例如下图,并分为3个脚本,分别画3个交互图。方法二的设计是给每个用例画出一个交互图。

   我们在基于数据库的系统中进行分析、设计时经常会遇到这个问题。对于这个问题也是存在着不同的看法,有些人认为方法二比较好,A.Cockburn认为方法一比较好。我个人认为采用方法一比较好一些。采用方法二可能会限制分析人员的思路,从用例图可以发现用户真正的目的不是对记录进行增加、修改、删除,而应该是别的,比如学生转学这个需求也会涉及到这些操作,但是真正的需要不是进行这些操作,而是转学。而且如果采用方法二的方式进行分析,一个基于数据库的系统绝大部分的用例可能就是增加、删除、修改,这样系统的用例显示太多。  

6、用例建模的技巧:

  从角色的角度以主动语态编写用例。应该以主动语态来编写用例,而且应该从角色的角度来编写用例。用例的目的是理解用户如何对系统进行操作。

  不要忘记用户界面。系统用例经常引用用户界面元素,这些元素常常称为“边界”或“用户界面”项,例如 HTML页面和报表。用例有时也引用一些次要的用户界面元素,例如按钮或数据输入字段,但这种级别的细节并不太常见。

  创建用例模板。用例包含了相当数量的信息,这些信息可以轻易地以常见格式记载。您应该考虑开发自己的模板。

  始终如一地组织用例图。一般的做法是垂直地绘制继承和扩展关联,在基本用例下面绘制继承、扩展用例。通常水平绘制包含关联。注意,这些是简单的经验法则只要始终遵循这些法则,产生的图将很容易理解。

  不要忘记系统对角色行动的响应。用例既应该描述角色是如何与系统交互的,也应该描述系统如何响应这些交互。

  备选行动过程非常重要。如果一切顺利,使用的将是基本用例。但也不要忘记备选过程。引入备选过程是为了描述潜在的使用错误以及商业逻辑错误和异常。这些重要的信息对于驱动系统的设计来说很有必要,因此不要忘记在用例中对它们建模

2、用例的本质

  用例的本质并不是UML中的一个椭圆符号,而是描述系统中各个相关人员之间就系统的行为所达成的契约,它应用功能分解的方法,站在系统之外,使用文字表达系统的功能性需求。在UML中为了可视化使用一个椭圆来表示,用例的具体内容通过使用用例模板来表达。用例技术是迄今为止最为深刻、准确和有效的系统功能需求描述方法。

  用例技术有如下的一些特点:用例是一种半形化的方式,它不是使用一种形式化的语言,而是使用自然语言来描述需求。但是它却明确的提出了角色和用例的概念,以及角色和用例进行通讯的规则,以及用例模板的主要内容。严格的结构和形式会使需求变得生硬、无用,没有结构和形式的需求又不易交流。这种半形式结构使得人们的创造性得以发挥,也使得系统的最终用户能够轻松的阅读;在每个用例和所有的描述层次中,都描述了错误时的系统处理。系统复杂性大部分都是处理错误情况,这样能够在需求分析阶段检测出相关的问题进行分析,而不是在以后的阶段中发现。这是我在使用用例过程中最为深刻的一点,我们在写需求的时候仅仅描述正确的用户需求,很少提及错误情况;用例提供了可以在其上处理其他项目信息的骨架,从而实现用例驱动。

3、用例与需求

  很多人使用用例描述需求后,就会产生疑问用例和需求到底是什么关系。用例是需求,但并不是系统的全部需求,用例描述的只是功能性方面的需求。不要试图把所有的需求都以用例的方式表示出来。有些人认为用例可以表示所有的系统需求,因此用UML来表示那些事实上很难用用例表示的需求,这样做是不对的。用用例分析需求有如下的特点:

  1、用例从使用系统的角度描述系统中的信息,即站在系统外部观看系统的功能,而不考虑系统内部对该功能的具体实现方式。

  2、用例描述了用户提出的一些可能需求,对应一个具体的用户目标,用例可以促进与用户沟通、理解正确的需求,同时也可以用来划分系统与外部实体的界限,是面向对象系统设计的起点,是类、对象、操作的来源。

  3、用例是对系统行为的动态描述。

4、用例驱动

  可能很多人都听说过数据驱动、用例驱动这样的字眼。为什么说使用UML进行软件开发是用例驱动的?因为用例代表系统中各个相关人员之间就系统的行为所达成的契约,一个软件的开发就是从分析这些工作开始的。软件的开发过程分为需求分析、设计、实现、测试等阶段,用例把所有这些都捆绑再一起,用例分析的结果也为预测系统的开发时间和预算提供依据,保证项目的顺利进行,从各个方面综合起来讲软件开发是用例驱动的。

5、用例模板

    用例图只是简单地可视化描述系统,我们还需要对用例进行详细的说明。为了明确的描述用例我们需要一个用例模板,但是至今并没有统一的用例模板。用例模板的内容一般包括:简要描述、前置条件、后置条件、基本事件流、备选事件流等等。
  简要描述:对用例的角色、目的的简要描述。
  前置条件:执行用例之前系统必须要处于的状态,或者要满足的条件。
  后置条件:用例一旦执行后系统所处的状态。
  基本事件流:描述该用例的基本流程,指每个流程都“正常”运作时所发生的事情,没有任何备选流而只有最有可能发生的事件流。
  备选事件流:表示这个行为或流程是可选的或备选的,并不是总要总要执行它们。

下面是一个用例模板的示例:  

用例: < 编号 >< 名称 >

特征信息:

    用例在系统中的目标(用例目标描述)

    范围(当前考虑的是哪个系统)

    级别(概要任务/首要任务/子功能)

    前提条件(用例执行前系统用具有的状态)

    成功后继条件(用例成功执行后应具有的状态)

    失效后继条件(用例没有完成目标的状态)

    首要角色(与该用例关联的首要角色)

    触发(启动该用例执行的系统动作)

主要步骤:

    <步骤编号><动作描述>

扩展:

    <有变化情况的步骤编号><条件>:<动作或另外一个用例>

变异:

    <步骤或变化编号><变异列表>

相关信息:(可选)

    优先级(该用例对于系统组织的关键程度)

    性能目标(该用例的执行时间耗费)

    频度(该用例被执行的频度)

从属用例:(可选)

下属用例:

  与首要角色的联系渠道(包括交互式、静态文件、数据库等)

公开问题:(可选)

    列出关于该用例的未解决的问题

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值