设计模式 (3)用例图之二

  • 导言
  • 标识用例
    • 用例主序列与可替换序列
    • 场景
    • 如何识别用例
      • 有意义的目标
      • 用户观点而非系统观点
      • 用例命名
      • 用例的粒度
      • 小技巧
  • 用例关系
    • 执行者与用例之间的关联关系
    • 用例包含关系
      • 例子
      • 另一种包含关系-结构化冗长的用例
    • 扩展关系
      • 简介
      • 扩展关系的应用情况
      • 扩展关系需注意
    • 扩展点
      • 定义
    • 扩展点和扩展用例的示例
    • 泛化关系
    • 用例包
    • 实例
  • 总结

导言

前面一篇博文,我们介绍了用例的初步概念,参与者以及参与者分类和参与者是如何识别的,接下来我将介绍用例的标识和用例之间的关系以及一部分习题。

标识用例

为了确定系统中的用例,从考虑参与者及其与系统间的交互开始是有用的。每个用例描述了参与者和系统之间的交互序列。用这种方法,系统的功能性需求通过用例来描述,用例构建了系统的功能规约。然而,当开发用例时,重要的是避免功能分解。在功能分解中,多个小的用例描述系统的单个小功能,而不是描述对参与者提供有用结果的事件序列。

我们再看看银行系统的例子(第二篇文章提到过,没有看的请看一下第二篇文章)。除了从ATM机取款之外,参与者“ATM客户”也被允许查询账户或者在两个账户间转账。由于这些是由客户发起的带来不同有用结果的不同功能。因此查询和转账功能宜被建模为分离的用例,而不是成为原始用例的一部分。这样,客户就能启动三个用例,如下所示:

“取款”(Withdaw Funds)、“查询”(Query Account)和“转账”(Transfer Funds)三个用例。

用例主序列与可替换序列

用例的主序列描述参与者和系统之间最常见的交互序列。

用例主序列也会存在分支来描述参与者和系统之间不那么频繁的交互,这些可替换序列是与主序列偏离的,仅仅在某些环境(例如参与者向系统进行了错误的输入)下才执行的。用例中的可替换序列有时可以稍后和主序列合并起来,这取决于应用需求。可替换序列也在用例中描述。

场景

用例中的每个序列称为场景

一个用例通常描述了多个场景:一个主序列和多个可替换序列。请注意,场景是用例中一个完整的序列,因此场景可以始于执行主序列,然后在决策点接上一个可替换分支。比如,“取款”的一个场景开始于主序列中客户讲ATM卡插入读卡器,看到提示后输入PIN码,但是收到了一条错误消息,因为PIN码是错误的,接着再输入正确的PIN码。

如何识别用例?

有意义的目标

有没有意义?涉众说了算!

下面观看一组错误的用例图:

这组用例图的用例标识不正确,输入查询关键字和选择商品查询类别,只是用户进行操作的一个步骤,并不是用户想要达到的目标,用例是描述功能性需求的,也就是说,用例是描述功能的,也就是目标,换句话来说,就是用户通过系统要实现什么,我们可以看得出,这个错误的用例图,这两个用例只是步骤,那么用户选择商品查询类别和输入查询关键字,最重要的是要做什么,实际上用户只是想通过系统来查询商品信息。所以我们最后重画。

用户观点而非系统观点

下面看这个用例:

这个用例是错误的。因为用例的说明是以系统的方面进行叙述的。而不是以用户的角度。

用户角度进行修改

用例命名

用例的命名应该是以“动词+(宾语)”。与参与者构成了“主+动+(宾语)”结构。

慎用弱动词弱名词

弱动词:进行、使用、复制、加载、重复

弱名词:数据、报表、表格、表单、系统

用例的“粒度”

粒度原则:

用例要有路径,路径要有步骤。而这一切都是“可观测”的。

最常犯错误--把步骤当作用例

下面的例子是错误的

1.把执行者动作当作用例

2.把系统活动当作用例

3.CRUD泛滥

泛滥的例子

重构

小技巧

形式检查

【执行者】使用系统来【用例】

用例关系

当用例变得非常复杂时,用例之间的依赖可以用包含(include)和扩展(extend)关系来定义,其目的是使可扩展性最大化和复用用例。包含用例(includion use cases)用来标识多个用例中的共同的交互序列,这些共同的交互序列能被抽取出来和复用。

执行者与用例之间的关联关系

在用例图中,执行者和用例之间进行交互,相互之间的关系用一根直线来表示,称为关联关系(Association)或通信关系(Communication)。

用例包含关系

一个共同交互序列可以从多个原始的用例中抽取出来,并形成一个新的用例,称为包含用例

包含用例是抽象的,即它不能独立执行。

一个抽象用例必须作为一个具体(即可执行)用例的一部分来执行。

当共同的功能分离到包含用例中时,该用例就能被其他用例复用。然后就可能定义旧用例的一个更简洁版本,该版本移除了共同交互序列。旧用例的这个简洁的版本就称为基用例(或具体用例),它包含了包含用例。

包含用例总是反映多个用例之间共同的功能。当共同的功能分离到包含用例中时,该包含用例就能被多个基用例(可执行的用例)复用。

包含用例没有特定的参与者。这是因为,参与者是包含了包含用例的基用例的参与者不同的基用例都会使用包含用例,所以包含用例可能被不同的参与者使用。

例子

有一个参与者“ATM客户”(ATM Customer)。系统初始分析标识三个用例:“取款”(Withdraw Funds)、”查询账户”(Query Account)和“转账”(Transfer Funds)。这三个是由该参与者启动的主要功能。在“取款用例”中,主序列包含了读ATM卡、验证客户的密码、检查客户在所请求的账号中有足够的资金接着,如果验证成功,则发出现金、打印凭条并退出卡片。对这三个用例进一步发现,每一个用例的第一个部分,即读ATM卡和验证客户密码是相同的。每个用例中重复该序列没有好处,因此,将PIN码验证这一序列分离成单独的包含用例,称为“验证PIN码”(Validate PIN),这个用例可以被(修改后的)“取款”、“查询账户”和“转账”用例使用。实例如下:

“取款”、“查询账户”、“转账”用例包含了“验证PIN码”的用例。

另一种包含关系-(结构化冗长的用例)

包含关系也能够用来组织一个冗长的用例。基用例提供参与者和系统之间高层次的交互序列。包含用例提供参与者和系统之间低层次的交互序列。

下面是一个实例:

“制造高容量部件”(Manufacture High-Volume Part)用例描述了制造一个部件的交互序列。该过程包含了接收生产该部件的原材料(在“接收部件”(Reveive Part)用例中描述),在每个工厂工作站执行生产步骤(在“高容量工作站处理部件”(Process Part at High-Volume Workstation)用例中描述)和运输已生产的部件(在“运输部件”(Ship Part)用例中描述)。

扩展关系

简介

在某些情形下,一个用例可能会非常复杂,有许多可替换的分支。扩展关系用来对用例可能采取的可替换路径进行建模。如果一个用例有太多可替换的、可选的和异常的交互序列,那么它可能会变得非常复杂。

针对上述的解决方案是将可替换或可选的交互序列分离成单独的用例。该新用例的目的是扩展旧的用例(如果保持合适的条件)。被扩展的用例称为基用例,用来扩展的用例称为扩展用例

在某些条件下,基用例能通过在扩展用例中给出的描述进行扩展。根据哪个条件为真,基用例能以不同的方式进行扩展。

扩展关系的应用情况

扩展关系可用于以下情况:

展示基用例只在某些环境下执行的有条件的部分

对复杂或可替换的路径

扩展关系需注意

一方面,基用例不依赖于扩展用例。

另一方面,扩展用例依赖于基用例并只在基用例中引起它执行的条件为真时才执行。

一个扩展用例可以扩展一个以上的用例

一个基用例能被多个扩展用例扩展

扩展点

定义

扩展点是用来规定基用例能被扩展的精确位置。

一个扩展用例只可以在这些扩展点上扩展基用例

每个扩展点都被赋予了一个名称。扩展 用例对于扩展点有一个插入片段,该片段在其基用例中扩展点的位置处插入。

片段定义了达到扩展点时所执行的行为片段

当用例的一个实例被执行并到达了基用例中的扩展点时,如果条件满足,则用例的执行将转移到扩展用例中的相应片段。在片段完成后,执行再转移回基用例。

带着多个扩展用例的扩展点可用于对多个可替换情况建模,其中每个扩展用例规定了一个不同的可替换。

要设计扩展条件,使得在任何给定的情况下只有一个条件能为真,这样只有一个扩展用例会被选择。

扩展条件是在用例运行的运行时设定和更改的。

扩展点和扩展用例的示例

考虑下面的用例图展示的例子:

在基用例“顾客付款”(Checkout Customer)中声明一个名为“付款”(Payment)的扩展点。基用例处理顾客结账。三个扩展用例处理付款类型:“现金结账”(Pay by Cash)、“信用卡结账”(Pay by Credit Card)和“借记卡结账”(Pay by Debit Card)。为每个扩展用例提供一个选择条件。扩展关系使用扩展点名称和选择条件来标注。

互斥选择条件分别是[现金付款]、[信用卡付款]、[借记卡付款]。用例执行期间,取决于客户选择如何付款,合适的选择条件会置为真。

泛化关系

当多个用例共同拥有一种类似的结构和行为的时候,可以将它们的共性抽象成为父用例,其他的用例作为泛化关系中的子用例。

在用例的泛化关系中,子用例是父用例的一种特殊形式,子用例继承了父用例所有的结构、行为和关系。

泛化关系一般很少使用。

在COMET方法中,泛化的概念局限于类。扩展关系已经足以处理用例的变化性。

用例包

对于大型系统,不得不处理用例模型中的大量用例经常是很难操作的。

解决这种增大问题的一个好方法是引入用例包,将相关用例分组在一起。如此,用例包便能表示那些描述系统的主要功能子集的高层次需求。

因为参与者经常启动和参与相关的用例,所以用例能基于使用它们的主要参与者来分组成包。适用于一组相关用例的非功能性需求可以分配到包含这些用例的用例包中。

例如,“应急监控系统”中,系统的主要参与者是“远程传感器”(Remote Sensor)、“监控操作员”(Monitoring Operator)和“应急管理员”(Emergency),每一个都启动和参与多个用例。如下图展示应急监控系统中用例包的例子,名为“应急监控用例包”(EmergencyMonitoringUseCasePackage),包含了4个用例。”监控操作员”是用例“查看警报”和“查看监控数据”的主要参与者,是其他用例的次要参与者。“远程传感器”是“生成警报”(Generate Alarm)用例和“生成监控数据”(Generate Monitoring Data)用例的主要参与者。

实例

1.某酒店订房系统描述如下:

(1) 顾客可以选择在线预订,也可以直接去酒店通过前台服务员预订;

(2) 前台服务员可以利用系统直接在前台预订房间;

(3) 不管采用哪种预订方式,都需要在预订时支付相应订金;

(4) 前台预订可以通过现金或信用卡的形式进行订金支付,但是网上预订只能通过信用卡进行支付;

(5) 利用信用卡进行支付时需要和信用卡系统进行通信;

(6) 客房部经理可以随时查看客房预订情况和每日收款情况。

构造该系统的用例模型。

解:

解决方案——识别执行者

(1) 顾客可以选择在线预订,也可以直接去酒店通过前台服务员预订;

(2) 前台服务员可以利用系统直接在前台预订房间;

(3) 不管采用哪种预订方式,都需要在预订时支付相应订金;

(4) 前台预订可以通过现金或信用卡的形式进行订金支付,但是网上预订只能通过信用卡进行支付;

(5) 利用信用卡进行支付时需要和信用卡系统进行通信;

(6) 客房部经理可以随时查看客房预订情况和每日收款情况。

解决方案——识别用例

(1) 顾客可以选择在线预订,也可以直接去酒店通过前台服务员预订;

(2) 前台服务员可以利用系统直接在前台预订房间

(3) 不管采用哪种预订方式,都需要在预订时支付相应订金

(4) 前台预订可以通过现金或信用卡的形式进行订金支付,但是网上预订只能通过信用卡进行支付;

(5) 利用信用卡进行支付时需要和信用卡系统进行通信;

(6) 客房部经理可以随时查看客房预订情况每日收款情况

解决方案——绘制用例图

总结

目前为止,我们已经介绍完用例图,后续会接连介绍其他图。

时间: 2024-10-06 13:57:58

设计模式 (3)用例图之二的相关文章

Java经典23种设计模式之结构型模式(二)

接上篇,本文介绍结构型模式里的组合模式.装饰模式.外观模式. 一.组合模式(Composite) 组合模式:将对象组合成树形结构,表示"部分--整体"的层次结构.最终达到单个对象和组合对象的使用具有一致性.单看这句话貌似有点抽象,其实比较简单. 以李云龙的独立团为例,目的要统计赵嘉宇一战共歼灭敌人多少个.最高的级别是团,一个团有若干个营,一个营有若干个排,一个排有若干个战士.(为了简化问题,排下面就不设行政单位了).很自然的,李云龙给营长开会回去给老子统计.营长回去给各个排长开会,赶紧

[转]使用设计模式改善程序结构(二)

使用设计模式改善程序结构(二) 在本系列的 第一篇文章中,描述了如何通过设计模式来指导我们的程序重构过程,并且着重介绍了设计模式意图.动机的重要性.在本文中我们将继续上篇文章进行讨论,这次主要着重于设计模式的适用性,对于设计模式适用性的掌握有助于从另一个不同的方面来判断一个设计模式是否真正适用于我们的实际问题,从而做出明智的选择. 1. 回顾 在上一篇文章中,我们给出了一个使用设计模式来改善程序结构的例子,着重介绍了设计模式的意图.动机在我们程序重构过程中的指导作用. 现在,我们将关注设计模式的

设计模式学习笔记(十二:生成器模式)

1.1概述 将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示.这就是生产器模式的定义. 如果一个类中有若干个成员变量是其他类声明的对象,那么该类创建的对象就可以包含若干个其他对象作为其成员.习惯上把一个对象中的成员对象称作它的组件,例如,几何(Geometry)类含有三角形(Triangle)类.矩形(Rectangle)类和圆(Circle)类声明的对象,那么几何类就可以创建一个由三角形.矩形和圆形组成的几何图形,三角形.长方形和圆形就是当前几何图形中的组件. 但是,在编

设计模式 2/23 工厂模式(二)

先要给各位同学灌输一个思想,世间本无设计模式,用的人多了,自然就有了 没有太明显的优劣之分,只道是谁更适合 如果没法理解<<工厂>>,建议阅读上一篇 设计模式 2/23 工厂模式(一) ,毕竟是一个渐进明细的过程,急不来的 这一篇分享 工厂模式 回想一下简单工厂,我们把具体类的实例化工作放在一个工厂方法里面来执行. 同时故意在上一篇提到了开放-封闭原则. 仔细想象看看上一篇的代码,到底有没有遵守这个原则,或者说这个原则有没有被严格意义的遵守,或者说遵守的程度是多少. 如果我们要新增

设计模式C++学习笔记之二(Proxy代理模式)

代理,一看名字就知道这只是个中介而已,真实的执行者在代理的后面呢.cbf4life在他的书里提的例子也很有趣,更详细的内容及说明可以参考原作者博客:cbf4life.cnblogs.com.现在贴代码,以方便随用随取. 2.1.解释 main(),西门庆 IKindWomen,接口 CWangPo,代理 CPanJinLian,实际执行者之一 CJiaShi,实际执行者之二 说明:代理和实际执行者派生于共同的接口,代理拥有实际执行者的实例.代理的每一个函数(接口的实现函数),直接调用实际执行者的

设计模式C#实现(十二)——装饰模式

意图 0 适用性 1 结构 2 实现 3 效果 4 参考 5 意图 动态的给一个对象添加一些额外的职责. 适用性 动态的为单个对象添加职责而不影响其他对象 处理那些可以撤销的职责(? 在某些功能不需要时删除这些功能) 当不能采用生成子类的方法进行扩展时 结构 实现 设计一些饮料,这些饮料可以由顾客选择添加各种佐料.先是饮料的抽象类 abstract class Beverage { protected string Description = "Unknown Beverage"; p

Java经典23种设计模式之行为型模式(二)

本文接着介绍行为型模式里的解释器模式.迭代器模式.中介者模式. 一.解释器模式Interpret 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言的中的句子. 1.AbstractExpression(抽象表达式) 声明一个抽象的解释操作,这个接口为抽象语法树中全部的节点所共享. public abstract class Expression {    abstract void interpret(Context ctx);} 2.Expression

设计模式之特性&quot;大杂烩&quot;(二)

接口 接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合. 一. 特点 1.实现了接口,雷就可以支持接口所指定的所有属性的成员. 2.声明接口在语法上与声明抽象类完全相同,但不允许提供接口中任何成员的执行方式. 3.实现接口的类就必须要实现接口中的所有方法和属性. 4.接口的命名,前面要加一个大写字母'I'. 5.接口中的方法或属性前面不能有修饰符.方法没有有方法体. 二.抽象类与接口的区别 1.抽象类可以给出一些成员的实现,接口却不包含成员的实现. 2.抽象类的抽象成员可被子类部分实

UML学习——用例图(二)

1.什么是用例? 用例模型主要应用在工程开发的初期进行系统需求分析阶段,描述了系统具备什么功能,也就是说从用户的角度观察系统应该支持哪些功能,同时帮助系统分析员对系统功能有个全面的认识,从宏观上描述系统的行为. 用例模型包括的基本元素有:用例,角色,系统. 2用例的作用 一个系统中可以包含多个用例,引入用例可以给我们带来以下几点好处. (1)确定系统有哪些功能,这些功能是否可以满足需求,使用户和开发者之间达成共识. (2)使用统一的描述,为后续工作打下基础. (3)方便验收测试. 3.用例图的基