需求文档化与验证

AI WARNING

未进行对照审核。

需求文档化:为何与何物

在软件开发这个复杂的协作过程中,清晰、准确的沟通至关重要。需求文档化就是将经过分析和协商确定的用户需求、系统特性和约束条件以规范化的形式记录下来的过程。

为什么需要文档化需求?

根据 [Brooks1975] 的观点,软件开发属于任务间需要密切沟通协作的类型。文档化是促进这种沟通、确保信息准确传递的关键手段。主要原因包括:

  • 团队协作与沟通:为项目经理、架构师、设计师、程序员、测试人员、维护人员等不同角色提供统一的理解基础。
  • 知识传递与持久化:将需求固化下来,避免信息丢失或失真。
  • 契约与基线:作为用户与开发团队之间确认需求的依据,以及后续设计、开发、测试和变更控制的基线。
  • 项目管理:为项目估算、进度安排、人员分工提供基础。

标准化文档的价值

虽然沟通方式多样,但标准化的文档具有不可替代的优势:

  • 减少歧义:统一的结构和术语有助于减少误解。
  • 提高效率:读者可以快速定位所需信息。
  • 保证完整性:模板有助于避免遗漏关键信息。

主要的需求文档类型

需求文档最常见的两种形式是用例文档和软件需求规格说明书(SRS)。

用例文档(Use Case Document)

用例文档用户角度出发,主要通过用例(Use Case)来描述用户(或其他系统)如何与待开发的软件系统交互以达成特定目标。

  • 核心职责:将问题域信息和用户需求传递给系统设计者。
  • 视角:外部用户视角。
  • 侧重点交互流程和用户目标的实现步骤。
  • 基础:以一次完整的交互(一个用例)为基本单元。
  • 价值:用例文档以用户故事的形式呈现需求,易于用户理解和确认,并能有效驱动后续的设计和测试。

用例文档结构示例

  1. 文档信息:标题、作者、版本历史、目的、范围、读者、参考文献、术语定义、文档约定等元数据和导读信息。
  2. 用例图或列表:使用 UML 用例图(Use Case Diagram)或列表,宏观展示系统包含的所有用例以及参与者(Actor)与用例的关系,还有用例之间的关系(如包含、扩展)。
  3. 用例描述:对每个用例进行详细描述,通常包括:
    • 用例 ID 和名称
    • 参与者
    • 前置条件(Preconditions)
    • 后置条件(Postconditions)
    • 基本流程(Basic Flow)/主成功场景(Main Success Scenario):描述用例成功完成的典型步骤。
    • 扩展流程(Alternative/Exception Flows):描述可能出现的各种替代路径、异常情况或错误处理。

软件需求规格说明书(Software Requirements Specification, SRS)

软件需求规格说明书(SRS) 则从软件产品角度出发,以系统级需求列表的方式,更全面、详细、精确地描述软件系统必须提供的功能、性能、接口、约束以及质量属性等。

  • 核心职责:精确定义软件「是什么」和「做什么」,作为开发和验收的标准。
  • 视角:内部产品视角。
  • 侧重点独立的、可验证的需求条目
  • 基础:以一次交互中的系统处理细节或一个独立的系统特性为基本单元。
  • 常用标准:IEEE 830-1998 标准提供了经典的 SRS 模板。

SRS 文档结构示例

  1. 引言(Introduction):目的、范围、定义、缩写、参考文献、文档概述。
  2. 总体描述(Overall Description):产品前景、产品功能(摘要)、用户特征、约束、假设与依赖。
  3. 详细需求(Specific Requirements):这是 SRS 的核心部分,可以有多种组织方式,常见的是按功能、接口、模式等组织。
    • 对外接口(External Interfaces):用户接口、硬件接口、软件接口、通信接口。
    • 功能需求(Functional Requirements):描述系统应具备的功能。通常会按系统特性(System Feature) 组织,每个特性下包含:
      • 特性描述
      • 刺激/响应序列(Stimulus/Response Sequences)
      • 相关的具体功能需求点(通常带有唯一 ID)
    • 性能需求(Performance Requirements):响应时间、吞吐量、资源利用率等。
    • 设计约束(Design Constraints):标准符合性、硬件限制等。
    • 质量属性(Quality Attributes):可靠性、可用性、安全性、可维护性、可移植性等。
    • 其他需求
  4. 附录(Appendices)
  5. 索引(Index)

用例文档 vs. SRS

特性 用例文档(Use Case Document) 软件需求规格说明书(SRS)
视角 用户视角 产品/系统视角
主要内容 用户与系统的交互流程(How) 系统需满足的功能与特性列表(What)
组织方式 以用例(用户目标) 为中心 以系统特性/功能/接口等为中心
侧重点 交互过程、业务价值 独立、精确、可验证的需求条目
读者 用户、业务分析师、部分开发者/测试者 开发团队、测试团队、项目经理、维护者
关系 可以作为 SRS 功能需求的输入和补充 更全面、更精确,是开发和验收的主要依据

在实践中,两者常结合使用。用例帮助理解业务场景和用户交互,SRS 则提供精确的技术规格。有时,简单的项目或时间紧张时,可能用详尽的用例文档代替部分 SRS 内容。

高质量需求文档的特征与写作要点

无论是用例文档还是 SRS,都需要遵循一些通用的技术文档写作原则和特定的需求书写规范。

技术文档通用写作要点

  1. 简洁(Concise):避免冗余和复杂的修辞,使用简单直接的语句。

  2. 精确(Precise):

    • 避免使用模糊、有歧义的词汇。下表是一些常见歧义词汇及其改进建议(参考表 7-1):

      歧义词汇 改进方法
      可接受的、足够的 具体定义可接受的标准,说明系统如何判断。
      依赖 明确依赖类型(数据、服务、资源)和原因。
      有效的 明确「有效」的具体含义和衡量标准。
      快的、迅速的 明确时间或速度的最小值或可接受范围(ms\pu{ms}, s\pu{s})。
      灵活的 描述系统为响应变化可能发生的具体变更方式。
      改进的、更好的、优越的 定量说明改进的程度和效果(在特定功能领域)。
      包括但不限于、等等、诸如此类 尽可能列举所有可能性,否则无法设计和测试。
      最大化、最小化、最优 说明参数可接受的最大/最小值范围。
      一般情况下、理想情况下 增加对异常和非理想情况下的行为描述。
      可选择地 明确是系统、用户还是开发人员进行选择。
      合理的、必要的、适当 明确判断标准。
      健壮的(Robust) 显式定义系统如何处理异常和预期外操作。
      不应该 尽量用肯定方式陈述,描述系统应该做什么。
      最新技术水平的 定义其具体含义,例如符合某项特定标准或采用某种特定技术。
      充分的 说明「充分」具体包含哪些内容。
      支持、允许 精确定义系统的功能,以及这些功能组合起来支持的能力
      用户友好的、简单的、容易的 描述具体的系统特性(如响应时间、点击次数、界面布局)来说明用户期望。
  3. 易读/可查询(Readable/Queryable):

    • 有效利用辅助元素:引言(明确目的、范围、读者)、目录、索引。
    • 系统化组织内容
      • 使用相同的语句格式描述相似信息。
      • 使用列表或表格组织独立、并列信息。
      • 使用编号表达关系(顺序、嵌套、层次)。
      • 对图、表、章节、具体信息内容进行编号和标识。
  4. 易修改(Modifiable):

    • 保持独立性:将需求分解为独立的、内聚的单元。
    • 唯一标识(ID):为每个需求条目(尤其是 SRS 中)分配唯一的、持久的标识符(如 REQ-F-001),便于跟踪和引用。可以使用层级编号(如 1, 1.1, 1.1.1)或功能/任务/步骤命名(如 FunctionName.TaskName.StepName)。
    • 引用而非重复(Reference, not Repeat):当需要在文档不同地方提及相同信息时,使用 ID 或交叉引用,而不是复制粘贴。这能确保修改时的一致性。

需求书写要点

  1. 使用用户术语:尽量使用用户和问题领域的语言,避免不必要的计算机术语,确保用户能理解和验证。
  2. 可验证(Verifiable):需求描述必须是具体的、可测量的。避免使用主观或模糊的词语(如「快」「好」「用户友好」),应量化指标(如「响应时间小于 1 s\pu{1s}」、「完成任务的点击次数不超过 3 次」)。
  3. 可行(Feasible):需求必须在已知的技术、时间、成本和资源约束下是可能实现的。这需要开发人员进行评估,有时需要通过原型验证。例如,「系统必须 100% 可用」通常是不可行的(应描述为具体可用性指标,如 99.99%)。

SRS 编写要点

  1. 充分利用标准模板:如 IEEE 830,确保结构完整,内容位置得当,便于读者查找信息。
  2. 保持完备性(Complete):不能遗漏重要需求或必要信息。需要基于业务需求分析,发现遗漏点。标记待定项(TBD - To Be Determined)。
  3. 保持一致性(Consistent):不同需求之间不能相互矛盾。需要评审来发现冲突。
  4. 为需求划分优先级(Prioritized):明确需求的重要性、紧急性、风险、成本等,以便在资源受限时做出取舍。可以使用高中低或 1-10 的量化等级。

需求评审练习

  • "After the payment process is complete, the relevant information should be appended to a log file."
    • 问题: 模糊/不完整(b/d)。 "relevant information" 是什么信息?日志文件的格式、位置、追加方式是什么?这导致需求难以验证。应具体说明需要记录的数据字段。
  • "The system should be constructed so that it will be easy to add new functionality in the future."
    • 问题: 模糊/不可验证(b/d)。 "easy" 如何定义和衡量?这是个好的目标,但作为需求太模糊。应转化为具体的质量属性需求,如遵循某种设计模式、提供插件接口、模块化设计等。
  • "The price of a gasoline purchase is computed as the price per gallon for the type of gas purchased, multiplied by the number of gallons purchased (use two decimal points for representing fractions of gallons)."
    • 问题: 基本可行(e)。 这个需求描述比较清晰、具体、可验证。明确了计算方法和小数位数。
  • "The system should be available 24 hours a day, 7 days a week."
    • 问题: 可能不现实/不可行(c)。 100% 可用性几乎不可能达到,维护、升级、意外故障总是可能发生。应改为具体的可用性指标,如 "99.95% uptime excluding scheduled maintenance windows"。

需求验证(Requirements Validation)

需求验证是确保编写的需求文档准确反映用户意图、满足用户需求,并且是完整、一致、可行的过程。主要方法包括评审、开发测试用例和度量。

评审(Review)

需求评审是发现需求文档错误和遗漏的最常用且有效的方法。

  • 重要性:需求阶段引入的错误修复成本最低,忽视验证是项目的主要风险之一。
  • 参与者:应包括客户/用户、领域专家、业务分析师、开发人员代表、测试人员代表等。技术人员和用户共同参与能发现不同类型的问题。
  • 用户关注点:用户通常对场景(Scenarios) 和线索(Threads)(即端到端的业务流程)最感兴趣,通过这些可以更好地理解系统是否满足其业务需求。
  • 使用检查列表(Checklist):提供结构化的检查项,帮助评审人员系统地发现问题。

需求评审检查列表要点

  • 组织与完整性:引用正确?详细程度一致?为设计提供足够基础?需求优先级确定?接口定义完整?需求无遗漏?错误处理已定义?
  • 正确性:无冲突或重复?表达清晰简洁准确?可验证?在项目范围内?无内容或语法错误?在资源内可行?
  • 质量属性:性能目标合理?安全防护考虑周全?其他质量属性(可靠性、可用性等)已量化并平衡?
  • 可跟踪性:需求 ID 唯一?每个业务需求都有对应的功能需求满足?每个功能需求都能追溯到高层需求?
  • 特殊问题:是真正的需求而非设计/实现方案?使用用户语言而非计算机术语?

开发系统测试用例(Developing System Test Cases)

在需求阶段就尝试为需求编写测试用例,是另一种有效的验证方法。如果一个需求难以或无法为其编写测试用例,则该需求很可能存在问题(如模糊、不完整、不可验证)。

  • 过程
    1. 开发测试用例套件(Test Case Suite):以需求(如 SRS 中的功能点)或用例为线索,将相关的测试场景组织在一起。例如,为「用户登录」功能创建一个套件,或为「处理销售」用例创建一个套件(如 TUS1, TUS2, TUS3)。
    2. 开发具体测试用例(Test Case):针对套件中的每个场景,使用基于规格的测试技术(如等价类划分、边界值分析、因果图等)设计具体的输入数据、操作步骤和预期输出。
  • 需求覆盖:通过映射关系,确保每个(重要的)需求至少被一个测试用例套件或具体测试用例所覆盖。

测试用例示例(销售处理 TUS1 - 非会员现金购买)

测试用例 ID 输入 - 商品信息 输入 - 特价 输入 - 赠品 输入 - 支付现金 预期输出 覆盖流程(基于用例)
TUS1-1 无商品 不做处理,关闭销售任务 (异常)
TUS1-3 商品 A(¥35),商品 B(¥50) ¥85 无找零,系统行为满足后置条件(如库存减少,销售记录生成) 正常流程 5-8a
TUS1-4 商品 A(¥35),商品 B(¥50) 商品 A 特价 ¥20 ¥100 找零 ¥30(50+20=70),系统行为满足后置条件 正常流程 5-8a

度量(Measurement)

通过量化指标来评估需求的规模、复杂度和潜在问题。

  • 常用度量指标
    • 用例数量
    • 平均每个用例的场景数量(基本流程+扩展流程)
    • 平均用例行数(衡量粒度)
    • 软件需求数量(SRS 中的独立需求条目数)
    • 非功能需求数量
    • 功能点数量(Function Points)
  • 度量的意义
    • 发现异常:平均场景数过低可能意味着异常情况考虑不周;平均用例行数过大或过小可能说明用例划分粒度不当。
    • 评估均衡性:用例数量、需求数量、功能点数量之间应大致成比例。如果某个指标与其他指标差距悬殊,可能存在需求遗漏或文档问题。
    • 估算依据:为项目规模、工作量和成本估算提供数据支持。

功能点度量(Function Point Analysis, FPA)

功能点是一种独立于编程语言和开发方法的、用于度量软件功能规模和复杂度抽象单位。它在需求阶段估算软件规模比代码行(LOC) 更为稳定和准确。

五种基本功能点类型

  1. 外部输入(External Inputs, EI):处理来自系统边界外的数据或控制信息,并维护至少一个内部逻辑文件(ILF)。例如,用户提交的表单数据、导入的文件。
  2. 外部输出(External Outputs, EO):向系统边界外发送经过处理的数据或控制信息。通常包含导出数据、计算结果、生成的报告、确认信息、错误提示等。例如,屏幕显示的报表、打印的账单。
  3. 外部查询(External Inquiries, EQ):一种特殊的输入输出组合,输入触发数据检索,输出是检索结果,且不更新内部逻辑文件(ILF)。通常是用户的即时「命令」请求。例如,点击按钮查询订单状态、使用热键获取帮助信息。
  4. 内部逻辑文件(Internal Logical Files, ILF):系统内部维护的、用户可识别的逻辑相关数据组或控制信息组。通常指数据库表、逻辑文件等持久化数据存储。
  5. 外部接口文件(External Interface Files, EIF):系统使用的、由其他系统维护的逻辑相关数据组或控制信息组。即系统需要读取的外部数据文件或接口。

功能点计算步骤

  1. 识别功能点类型并计数

    • 遍历需求文档(用例、SRS),识别出系统包含的 EI, EO, EQ, ILF, EIF。
    • 根据每个功能点的复杂度(通常评估其包含的数据元素类型 DETs 和记录元素类型 RETs 或文件类型引用 FTRs),将其划分为简单(Simple)、中等(Average)、复杂(Complex) 三个等级。
    • 统计每个类型和复杂度组合的数量。
  2. 计算未调整功能点(Unadjusted Function Points, UFP):

    • 使用预定义的权重因子(根据类型和复杂度确定,见下表,参考表 7-6)乘以对应的计数,然后求和。
    • UFP=i=15j=13(Countij×Weightij)\text{UFP} = \sum_{i=1}^{5} \sum_{j=1}^{3} (\text{Count}_{ij} \times \text{Weight}_{ij})
      • 或者简化为课件中的公式(假设已按复杂度加权计数):UFP=j=15(Cj×fj)\text{UFP} = \sum_{j=1}^{5} (C_j \times f_j),其中 CjC_j 是第 jj 类功能点的数量, fjf_j 是其(假定为中等等级或根据实际评估的)权重。

    | 功能点类型 | 简单(Simple) | 中等(Average) | 复杂(Complex) |
    | :-- | :-- | :-- | :-- |
    | 外部输入(EI) | 3 | 4 | 6 |
    | 外部输出(EO) | 4 | 5 | 7 |
    | 外部查询(EQ) | 3 | 4 | 6 |
    | 内部逻辑文件(ILF) | 7 | 10 | 15 |
    | 外部接口文件(EIF) | 5 | 7 | 10 |

    • 示例(销售任务 - 中等系统):
      • 输入(EI):3 个(假设中等复杂度) -> 3×4=123 \times 4 = 12
      • 输出(EO):11 个(假设中等复杂度) -> 11×5=5511 \times 5 = 55
      • 查询(EQ):7 个(假设中等复杂度) -> 7×4=287 \times 4 = 28
      • 逻辑文件(ILF):12 个(假设中等复杂度) -> 12×10=12012 \times 10 = 120 (注意:课件 p48 识别出 12 个逻辑文件,p47 需求列表也能对应上)
      • 对外接口(EIF):0 个 -> 0×7=00 \times 7 = 0
      • UFP=12+55+28+120+0=215\text{UFP} = 12 + 55 + 28 + 120 + 0 = 215
  3. 计算技术复杂度因子(Value Adjustment Factor, VAF):

    • 评估 14 个通用系统特征(GSCs) 对项目的影响程度,每个特征评分范围 0 (无影响) 到 5 (非常重要)。
      1. 数据通信
      2. 分布式数据处理
      3. 性能
      4. 高负荷运行配置
      5. 事务速率
      6. 在线数据输入
      7. 终端用户效率
      8. 在线更新
      9. 复杂处理
      10. 可重用性
      11. 安装简易性
      12. 操作简易性
      13. 多点部署
      14. 易变更性
    • 计算总影响度 DI=i=114Fi\text{DI} = \sum_{i=1}^{14} F_i
    • VAF=0.65+(0.01×DI)\text{VAF} = 0.65 + (0.01 \times DI)
    • 示例(销售任务):
      • 假设 14 项评分总和 DI=40\text{DI} = 40
      • VAF=0.65+(0.01×40)=0.65+0.40=1.05\text{VAF} = 0.65 + (0.01 \times 40) = 0.65 + 0.40 = 1.05
  4. 计算调整后功能点(Adjusted Function Points, FP):

    • FP=UFP×VAF\text{FP} = \text{UFP} \times \text{VAF}
    • 示例(销售任务):
      • FP=215×1.05=225.75\text{FP} = 215 \times 1.05 = 225.75

功能点提供了一个相对客观的软件规模度量,可用于成本估算、生产率度量和项目比较。

总结

需求文档化与验证是软件工程中至关重要的环节。通过规范的用例文档软件需求规格说明书(SRS),可以有效地沟通和记录需求。遵循技术文档写作要点需求书写规范,可以提高文档质量。通过评审开发测试用例需求度量(尤其是功能点分析)等验证手段,可以确保需求的正确性、完整性和可行性,为项目的成功奠定坚实基础。