需求分析 (定义用例)

Published Sat 05 August 2017 in 软件工程

by HanXiao  


在 AUP 中, 需求也不是一次性分析完的, 会是一个不断迭代精化的过程.

先来个总结:

  • 摘要/非正式/用例图, 用来快速收集需求, 表达用户可以利用系统作什么, 是粗粒度级别的
  • 详述用例, 用来详细的描述完成用例的所有步骤及各种变化, 不仅仅是用户的操作, 还包括系统处理的事件流和业务流, 注意是黑盒, 不涉及代码.

迭代过程

  1. 先进行高阶需求分析, 仅仅确定用例的名称, 以及关键的非功能性需求
  2. 从高阶需求列表中选取 10% 的列表项进行详细的分析 1. 核心架构 2. 高业务价值 3. 高风险
  3. 结合早期时间定量的迭代开发, 进行迭代和进化式需求分析, 并且引入频繁的涉众参与、评估和对局部结果的反馈
  4. 根据第 3 步的反馈, 返回第 1 步进行下一轮迭代

需求分类 (FURPS+)

  • 功能性 (Functional): 特性、功能、安全性
  • 可用性 (Usability): 人性化因素、帮助、文档
  • 可靠性 (Reliability): 故障频率、可恢复性、可预测性
  • 性能 (Performance): 响应时间、吞吐量、准确性、有效性、资源利用率
  • 可支持性 (Supportability): 适应性、可维护性、国际化、可配置性
  • 辅助性及次要的因素 (+): + 实现 (Implementation): 资源限制、语言和工具、硬件等 + 接口 (Interface): 强加于外部系统接口之上的约束 + 操作 (Operation): 对其操作设置的系统管理 + 包装 (Packaging): 例如物理的包装盒 + 授权 (Legal): 许可证或其它方式

如何管理?

需求分析会通常会有两个产出:

  • 用例模型: 管理功能需求
  • 补充性规格说明: 管理所有非功能需求

用例模型

用例模型并不是特指 UML 用例图, 用例图只是用例模型的一种方式.

用例是 OOA 阶段非常重要的产出 (另外一个是领域), 也是 OOD 阶段非常重要的输入, OOD 阶段的关键目标之一是用例实现, 即通过 UML 交互图来描述用例基于软件对象如何在设计模型中实现.

什么是用例?

  • 用例就是功能性需求, 或者说是用来描述系统的功能性需求
  • 通过编写使用系统实现用户目标的情节 (流程) 来发现和记录功能性需求 (强调的是 FURPS+ 中的 F)
  • 用例的本质是文本形式的情节描述, UML 只是辅助工具, 用例的重点是用文本描述出用户如何使用系统, 而不是 UML 图形, 但并不是 UML 用例图毫无用处, 在用例收集阶段, 可以用来快速构建用例语境图. 参考下面的如何记录
  • 三种常用形式 + 摘要: 简洁的一段式概要, 通常用于主成功场景, 可用 UML 用例图替代 (目标: 用于早期需求分析, 快速了解主题和范围) + 非正式: 非正式的段落格式, 用段落覆盖不能场景 (目标和摘要一样) + 详述: 详细的所有步骤及各种变化 (事件流), 包含补充部分, 如前置条件和成功保证 (目标: 用于详细描述下一次迭代的 10 %~20% 用例)

用例元素

  • 参与者: 具有行为的事物, 可以是人、另一个系统等 + 主要参与者: 具有用户目标, 并通过使用系统功能来完成 (目标: 发现驱动用例的用户目标, 主要是人) + 协助参与者: 为系统提供服务 (目标: 为了明确外部接口和协议, 主要是另一个系统) + 幕后参与者: 在用例行为中具有影响或利益, 但又不是主要或协助参与者, 如政府税收机构 (目标: 为了确保确定并满足所有必要的重要事物)
  • 场景: 参与者与系统间的交互, 简单的说就是用户操作了什么
  • 用例: 场景的集合, 描述参与者如何使用系统来实现其目标

如何发现用例 (寻找参与者与目标)?

首先应识别出系统边界, 然后在系统边界内找出主要参与者, 然后分析其目标. 用例强调参与者的目标和观点, 所以提问总是围绕参与者目标而不是系统本身.

  1. 谁来使用系统?
  2. 谁来启动和停止系统?
  3. 谁来完成用户管理和安全管理?
  4. 谁来完全系统管理?
  5. 时间是参与者吗? 即需要定时任务吗?
  6. 当系统失败时, 是否存在监控进程将系统重新启动?
  7. 软件升级是如何处理的? 是推模式, 还是拉模式?
  8. 除了人作为主要参与者外, 还有其他外部的软件或系统调用该系统的服务吗?
  9. 谁来考察系统活动或性能?
  10. 谁来考察日志? 是否可以远程检索?
  11. 系统发生错误或故障时应通知谁?

如何记录参与者与目标?

发现用例后, 有两种记录方式:

  1. UML 用例图 (推荐)
  2. 参与者 - 目标 列表, 如果使用这种方式, 该表可做为设想制品的一部分

用例的本质虽然是文本形式的情节描述, 但并不是每一次迭代都需要详述所有的用例, 可以用 UML 用例图快速收集需求 (代替摘要用例), 从而产出用例语境图. 迭代时, 从语境图中选取一部分进行详述.

UML 用例图中允许使用包含扩展两种关系, 虽然也可以绘制出用户在系统上实现目标的情节 (流程), 但 AUP 不建议使用用例图去描述流程控制, 因为 UML 比较专业, 为了让用户早期参与项目, 所以建议用文本形式进行详述. 当场景工作流复杂到文本无法描述时, UML 活动图是很好的选择.

UML 制图准则

  • 以本质风格编写用例, 摒除用户界面并且关注参与者的意图 + 本质风格: 摒除 UI 细节并集中于用户真实意图的用例风格 + 并不是说关注 UI 不好, 只是这并不是早期的需求分析工作
  • 用语应尽量简洁, 以动词开头, 删除没必要的词汇
  • 编写黑盒用例 + 不对系统内部工作、构件或设计进行描述 + 只通过职责来描述系统 + 规定系统必须做什么, 而不是如何去做 (这也正是分析与设计的区别)
  • 采用参与者和参与者目标的视点 + 关注系统的用户或参与者来编写需求, 询问其目标和典型情况 + 关注理解参与者所考虑的有价值结果

总结: 用例应产生对特定参与者具有价值的可观察结果.

详述用例

模板参考

alistair.cockburn.us 上提供的模板, 由 Alistair Cockburn 创建, 它是用例建模方法和畅销书的作者.

用例元素 注释
用例编号 (*) 用例的编号
用例名 (*) 以动词开始, 描述一个用户的具体动作
范围 (*) 要设计的是什么系统
级别 用户目标或者子功能
涉众及其关注点 (*) 关注该用例的人, 及其关注的地方
前置条件 值得告知读者的, 开始前必须为真的条件
成功保证(后置条件) (*) 值得告知读者的, 成功完成必须满足的条件
主成功场景 (*) 典型的、理想方式的成功场景
扩展 (*) 成功或失败的替代场景
特殊需求 相关的非功能性需求 (通常最终会整理到补充规格说明中)
技术和数据变元表 不同的 I/O 方法和数据格式
发生频率 影响对实现的调查、测试和时间安排
杂项 例如未决问题

带 (*) 的是相对重要的选项, 通常是必填项

编写指南

  • 级别分为用户目标或子功能, 大部分情况下都是用户目标级别, 子功能级别的含义在于当若干用例共享某同一批步骤时, 则将这批步骤分离出来, 创建成子功能级别用例, 以避免重复的公共文本
  • 用例编号, alistair.cockburn.us 上并没有要求, 是我加上的, 主要为了对用例进行整理、排序
  • 涉众及其关注点比看上去重要的多, 它捕获的是最原始的需求, 系统的目标就是实现涉众的关注点, 所以用例应该包含满足所有涉众关注点的事物
  • 前置条件成功保证(后置条件) + 前置条件是用户使用系统前的条件, 应只列出需要引起注意警惕的条件, 例如要使用 POS 机的话收银员必须先完成登录用例; 而有些条件也必须为真, 但并不值得写出, 如必须要有供电 + 成功保证是指用例场景成功后会产生的必然的影响 (即系统必须要执行的扫尾操作, 如更新账务和库存信息、生成票据等), 应该满足所有涉众需求, 通常会是主成功场景的最后几个步骤
  • 主成功场景 + 描述了满足涉众关注点的典型成功路径 (即所有涉众都得到理想状态) + 通常不包括任何条件或分支, 只有一条主成功路径, 因此要用”确认”语句, 而不是”是否”语句, 例如系统验证密码正确, 而不是系统检查密码是否正确, 所有条件或分支都应推延到扩展部分进行说明 + 描述中不要涉及 UI, 例如以下方式不可取: 用户在输入框中输入账号, 用户在下拉框中选择第二项 + 场景主要记录以下信息: * 参与者之间的交互 * 系统本身也是参与者之一, 每个步骤都要能找到操作人, 应按主动语态来描述, 如用户xxx, 系统xxx * 需指出参与者之间的交互信息 + 如果信息简单, 可直接在步骤中描述: 用户输入用户名和密码 + 如果信息复杂, 可在词汇表中进行定义: 用户输入注册信息 (参考词汇表 - 注册信息) * 确认过程 + 即系统对参与者输入的处理流程, 注意是业务流程, 所以不要暴露系统任何内部组件 + 如果流程过于复杂, 可以使用 UML 活动图 + 应将系统边界外的协助参与者体现出来, 并标明是外部参与者, 否则研发会误认为这个功能是属于系统边界内的 - 如果这个步骤是系统发起的, 可以描述成: 系统通过外部账务系统确认客户缴过费 - 如果这个步骤是用户发起的, 可以描述成: 用户通过系统从外部账务系统获取充值记录 * 系统的状态变更 + 通常和成功保证/后置条件有关联, 注意是黑盒描述, 例如系统记录销售信息, 而不是系统将销售信息写入数据库
  • 扩展 + 主要包括主成功场景的分支 + 与主成功场景相结合应该满足几乎所有涉众关注点 (有些非功能性关注点则应该放到补充规格说明中描述) + 由于扩展场景是主成功场景的分支, 因为通常用与主成功场景对应的序号来标识 * 如主成功场景中第一步的扩展用 1a、1b 这样描述 * 某些扩展是几个步骤共用, 如主成功场景第一步到第三步中都有可能出现的扩展则用 1-3a、1-3b 这样描述 * 还有些扩展贯穿整个主成功场景, 则用 *a、*b 这样描述 * 某些扩展可能需要执行其他用例 (或者扩展非常复杂, 并且有一定的通用性, 则可单独抽出来形成另一个用例), 此时使用下划线标识这是另一个用例, 如果是用有超链接功能的工具编写用例, 那么点击下划线应可跳转到其所标识的用例 * 在每一步的扩展结束时应重新回到主成功场景的步骤, 除非扩展指出来其他路径
  • 特殊需求, 这些需求最终会被整理到补充规格说明中作为整体来考虑 + 与本用例相关的非功能性需求 + 质量属性 (如性能、可靠性和可用性) + 设计约束 (通常对于 I/O 设备)
  • 技术和数据变元表 (翻译感觉有点问题, 原文是 Technology and Data Variations List), 介绍特殊的标准和技术, 指定必须如何实现系统 (而非实现系统哪些功能).

实例参考 《UML 和模式应用》 P50