赵星汉同学的技术博客 Software testing & software engineering

《Guide to the software engineering body of knowledge》笔记(一)

2024-12-09
Frank Xinghan Zhao


软件需求

定义软件需求

软件需求是软件工程中的核心概念,它定义了软件产品必须具备的属性,以解决现实世界中的特定问题。软件需求可以是自动化某人的部分任务以支持组织的业务流程、纠正现有软件的不足,或控制设备等。这些需求通常来源于多个组织层级的不同人员,他们以某种方式与软件将要运行的环境相关联。

软件需求的关键属性包括可验证性,即需求可以作为功能需求单独验证,或作为系统级别的非功能需求验证。验证某些软件需求可能困难或成本较高,因此软件需求、软件测试和质量人员必须确保需求在可用资源限制内可验证。

除了行为属性外,软件需求还具有其他属性,如优先级评级,以便在资源有限的情况下进行权衡;状态值,以便监控项目进度;通常软件需求具有唯一标识,以便在整个生命周期内进行软件配置管理。

软件需求分为产品需求和过程需求:

  • 产品需求:对要开发的软件的需求,例如“软件必须在学生注册课程前验证其满足所有先决条件”。
  • 过程需求:对软件开发过程的约束,例如“软件必须使用RUP过程开发”。

软件需求还分为功能需求和非功能需求:

  • 功能需求:描述软件要执行的功能,如格式化文本或调制信号。
  • 非功能需求:约束解决方案的需求,如性能、可维护性、安全性等。

此外,软件需求还涉及涌现属性(Emergent Properties),这些需求不能由单个组件解决,而是依赖于所有软件组件如何协同工作。例如,呼叫中心的吞吐量需求取决于电话系统、信息系统和操作员在实际运行条件下的相互作用。这种需求在系统设计中经常被看成“系统需求”,但系统需求的定义并不是很贴切,因为涌现需求并不一定是在系统层面上呈现。

最后,软件需求应尽可能明确和无歧义地表述,并在适当时量化。例如,呼叫中心软件必须提高中心的吞吐量20%;系统在任何一小时操作中产生致命错误的概率应小于$1 * 10^-8$。这些量化需求对于需求的理解和后续的设计和测试至关重要。

产品和过程需求

这一部分区分了两种类型的软件需求:产品需求和过程需求。

  • 产品需求(Product Requirements):指的是针对要开发的软件的需求。这些需求描述了软件应该具备的特性或行为,例如:“软件必须在学生注册课程前验证其满足所有先决条件”。产品需求关注的是软件产品本身应达到的标准和功能。

  • 过程需求(Process Requirements):指的是对软件开发过程的约束。这些需求可能直接影响软件开发的方法和步骤,例如:“软件必须使用RUP(快速统一过程)开发”。过程需求可能由开发组织、客户或第三方(如安全监管机构)直接施加。

一些软件需求可能隐含地产生过程需求。例如,选择验证技术可能影响软件开发的过程。过程需求有时也可能与资源、功能需求和非功能需求之间存在冲突。在大多数情况下,软件工程师不能单方面做出决定,而需要与利益相关者协商,以达成适当的权衡。这种决策过程对于合同来说很重要,因为它需要能够追溯到客户。

产品需求和过程需求的区分有助于在软件开发过程中做出合理的资源分配和优先级决策。了解这些需求有助于项目经理和开发团队在预算、技术、法规和其他约束条件下进行有效的权衡。

功能和非功能需求

这一部分区分了软件需求的两个主要类别:功能需求和非功能需求。

  • 功能需求(Functional Requirements):描述软件应该执行的具体功能,有时也被称为软件的能力或特性。功能需求可以通过编写有限的测试步骤来验证其行为。例如,格式化文本或调制信号等。功能需求通常与软件的业务逻辑和用户可见的行为直接相关。

  • 非功能需求(Nonfunctional Requirements):约束解决方案的属性,也被称为约束或质量需求。它们可以进一步分类,包括性能需求、可维护性需求、安全性需求、可靠性需求、互操作性需求等。非功能需求通常涉及系统的质量属性,它们定义了软件应该如何表现,而不仅仅是它需要做什么。例如,系统应该在2秒内响应用户请求,或者软件应该能够在高负载下保持稳定运行。

功能需求和非功能需求共同构成了软件的完整需求集,它们对于确保软件产品满足用户的实际需要和业务目标至关重要。功能需求确保软件能够执行预期的任务,而非功能需求则确保软件在执行这些任务时能够达到一定的质量标准。在软件开发过程中,这两类需求都需要被充分理解和明确定义,以便于设计、实现和验证软件产品。

涌现属性

涌现属性是指那些不能由单个组件单独解决的需求,而是取决于所有软件组件如何协同工作的需求。这些属性在单个组件层面上无法观察到,只有当所有组件作为一个整体相互作用时才会显现出来。例如,一个呼叫中心的软件吞吐量需求不仅取决于软件本身,还取决于电话系统、信息系统以及在实际运行条件下操作员之间的相互作用。

涌现属性对于系统架构至关重要,因为它们通常与系统的整体行为和性能相关。在设计和维护软件系统时,理解和识别这些涌现属性是非常重要的,因为它们可能会影响到系统的稳定性、性能和可扩展性。软件工程师需要考虑这些涌现属性,以确保软件系统在整体上满足所有利益相关者的需求和期望。

在实际的软件开发过程中,涌现属性可能会带来挑战,因为它们可能不会在早期的开发阶段显现,而是在系统投入使用后,随着用户行为和系统负载的变化而逐渐显现。因此,软件工程师需要采用适当的方法和工具来识别、分析和管理这些涌现属性,以确保软件系统的整体质量和性能。这可能涉及到系统的监控、性能评估和持续的优化工作。

需求的量化

1.5 可量化需求(Quantifiable Requirements):

在软件工程中,可量化需求是指那些可以以明确和无歧义的方式陈述的需求,如果可能的话,还应该以量化的形式表达。这样的需求特别重要,因为它们有助于避免依赖主观判断的模糊和不可验证的需求(例如“软件应该是可靠的”或“软件应该用户友好”)。对于非功能需求来说,这一点尤其关键。

可量化需求的重要性在于:

  1. 明确性和无歧义性:需求应该被清晰地定义,以减少误解和混淆的可能性,确保所有利益相关者对需求有共同的理解。

  2. 可验证性:需求应该是可验证的,这意味着应该能够设计测试用例来检查需求是否得到满足。

  3. 量化:当适当的时候,需求应该被量化,以便于更精确地定义和衡量。例如,一个呼叫中心软件的需求可能是提高中心的吞吐量20%,或者系统在任何一小时操作中产生致命错误的概率低于1 * 10^-8。

  4. 高级别和详细级别的需求:可量化的需求通常需要从高层次的需求中派生出详细的需求。例如,提高吞吐量的需求可能需要进一步细化为一系列具体的性能指标和系统架构决策。

  5. 对系统架构的影响:某些量化需求,如可靠性需求,可能会对系统架构产生重大影响,因为它们限制了系统设计和组件的选择。

在实践中,软件需求的量化有助于项目管理和控制,因为它提供了一种评估项目进度和成功的方法。它还有助于在资源有限的情况下进行权衡,因为量化的需求更容易与成本和时间估算相联系。因此,软件工程师在定义需求时应尽可能地使其可量化,以提高需求管理和项目成功的可能性。

系统需求

1.6 系统需求与软件需求(System Requirements and Software Requirements):

这一部分区分了系统需求和软件需求,并解释了它们之间的关系。

  • 系统需求(System Requirements):指的是整个系统的需求,包括硬件、软件、固件、人员、信息、技术、设施、服务和其他支持元素,以实现定义的目标。系统需求涵盖了用户需求、其他利益相关者的需求(如监管机构)以及没有可识别人类来源的需求。

  • 软件需求(Software Requirements):当系统中包含软件组件时,软件需求是从系统需求中派生出来的。软件需求专注于软件产品必须具备的特定功能和属性,以满足系统需求。

这一区分强调了在软件开发过程中需要考虑的两个层面的需求:

  1. 用户需求:通常被定义为系统客户或最终用户的需求量较少,而系统需求则更为广泛,包括了所有利益相关者的需求。

  2. 需求层次:系统需求提供了一个更高层次的视角,包括了软件需求在内的整个系统的需求。软件需求则是对系统需求中与软件相关的部分的进一步细化和具体化。

理解系统需求和软件需求之间的关系对于确保软件产品能够有效地融入整个系统并满足所有预期功能至关重要。软件工程师需要将系统需求转化为具体的软件需求,并确保这些软件需求得到妥善管理和实现。这种转化过程需要深入理解系统的上下文和目标,以及软件如何与系统的其他组件交互。

需求过程

过程模型

在软件需求知识领域(KA)中,过程模型主题旨在提供对需求过程的理解,强调需求过程不是软件生命周期中的一个独立前端活动,而是一个从项目开始就启动并在整个生命周期中不断细化的过程。这一主题涉及以下几个关键点:

  • 需求过程的持续性:需求过程不仅限于项目初期,而是贯穿于软件的整个生命周期。这意味着需求的识别、分析、规格说明和验证活动在整个项目周期内都在进行,并且随着项目进展而不断演化。

  • 需求作为配置项:在需求过程中,软件需求被识别为配置项,并使用与其他软件生命周期过程产品相同的软件配置管理实践进行管理。这有助于确保需求的变更得到适当的控制和跟踪。

  • 适应性:需求过程需要根据组织和项目的具体背景进行调整。不同的项目可能需要不同的需求过程模型,以适应特定的开发环境、团队结构、技术复杂性等因素。

  • 跨学科性质:需求过程本质上是跨学科的,涉及多个领域的专家和利益相关者。这要求需求专家在不同领域之间进行协调和沟通,确保所有相关方的需求和期望得到妥善处理。

  • 过程活动的配置:过程模型还涉及如何根据不同项目类型和约束条件配置需求过程的活动,例如需求的收集、分析、规格说明和验证。这包括确定哪些活动是必要的,以及如何有效地组织和执行这些活动。

  • 输入活动:过程模型还考虑了为需求过程提供输入的活动,如市场调研和可行性研究。这些活动有助于确定项目的方向和需求的优先级,从而影响需求过程的执行。

总的来说,2.1 过程模型主题强调了需求过程的动态性和复杂性,以及在软件工程中对这一过程进行有效管理的重要性。

过程参与者

这一主题涉及在软件需求过程中参与的各种角色。需求过程本质上是一个跨学科的过程,涉及多个利益相关者,他们对软件产品有不同的需求和期望。以下是一些关键的过程参与者及其角色:

  • 用户/操作员(Users/Operators):这一群体包括那些将操作软件的人。他们可能是一个多样化的群体,涉及具有不同角色和需求的人。

  • 客户(Customers):这一群体包括委托开发软件的人或代表软件目标市场的人员。客户可能对软件的具体功能和性能有明确的要求。

  • 市场分析师(Market Analysts):对于大众市场产品,可能没有委托客户,因此市场分析师需要确定市场的需求,并作为代理客户。

  • 监管机构(Regulators):许多应用领域,如银行和公共交通,受到监管。在这些领域中,软件必须符合监管机构的要求。

  • 软件工程师(Software Engineers):这些个体对开发软件有合法的利益,例如,通过重用组件或其他产品中的组件来提高开发效率。如果客户对特定产品有特定要求,这可能会影响组件重用的潜力,软件工程师需要仔细权衡自己的利益与客户的利益。

软件工程师的任务是在满足主要利益相关者的需求和预算、技术、监管等其他约束条件之间进行协商,以达成双方都能接受的权衡。这需要识别所有利益相关者,分析他们的“利益”性质,并收集他们的需求。

过程参与者之间的有效沟通是需求过程成功的关键。需求专家可能需要充当沟通的桥梁,调解软件用户(和其他利益相关者)与软件工程师之间的领域差异。在不同抽象层次上建立一组内部一致的模型,有助于促进软件用户/利益相关者与软件工程师之间的沟通。

需求获取技术

3.2 需求获取技术(Elicitation Techniques):

在软件工程中,需求获取技术是用于从不同来源收集需求信息的方法。这些技术帮助软件工程师理解用户的需求、期望和问题,从而能够更准确地定义软件的功能和特性。以下是一些主要的需求获取技术:

  • 访谈(Interviews)
    • 访谈是一种传统的手段,通过与利益相关者直接对话来收集需求。了解访谈的优势和局限性以及如何进行访谈是非常重要的。
  • 场景(Scenarios)
    • 场景提供了一个有价值的框架,用于提供用户需求的上下文。它们允许软件工程师通过“如果”和“如何完成”等问题,构建一个讨论用户任务的框架。最常见的场景类型是使用用例描述。
  • 原型(Prototypes)
    • 原型技术是澄清模糊需求的有力工具。它们可以像场景一样提供用户一个上下文,帮助他们更好地理解需要提供的信息。原型的范围可以从简单的纸张草图到软件产品的beta测试版本。
  • 引导会议(Facilitated Meetings)
    • 这些会议的目的是尝试实现汇总效应,即一群人可以比单独工作时更深入地洞察软件需求。这种方法可以促进头脑风暴和提炼想法,这些想法可能通过访谈难以浮现。
  • 观察(Observation)
    • 软件工程师通过沉浸在用户环境中,观察用户如何执行任务以及如何与软件工具和其他资源互动,来了解用户任务。这种方法可能相对昂贵,但也具有启发性。
  • 用户故事(User Stories)
    • 这是一种在敏捷方法中常用的技术,指的是用客户的语言简短、高层次地描述所需功能。一个典型的用户故事形式是:“作为<角色>,我想要<目标/愿望>,以便<收益>。”
  • 其他技术
    • 还有其他一系列支持需求信息获取的技术,从分析竞争对手的产品到应用数据挖掘技术,再到利用领域知识或客户请求数据库等。

需求获取技术的选择和应用取决于项目的特定情况、利益相关者的合作程度以及需求的复杂性。有效的需求获取是确保软件项目成功的关键步骤,因为它直接影响到软件是否能满足用户的实际需求和期望。

需求分析

需求分析是软件工程中一个重要的阶段,主要关注对收集到的需求进行深入分析,以确保它们的完整性、一致性和正确性。通过这一过程,软件工程师能够识别需求之间的冲突、界定软件的边界以及确定软件与其组织和操作环境的交互方式。以下是需求分析的几个关键点:

需求分类:

  • 需求可以根据多个维度进行分类,例如:
    • 功能需求与非功能需求:功能需求描述软件应执行的功能,而非功能需求则约束解决方案的属性(如性能、安全性等)。
    • 派生需求与直接需求:派生需求是从高层需求或涌现属性中提取的,而直接需求则是由利益相关者直接施加的。
    • 产品需求与过程需求:产品需求是对软件的需求,而过程需求则是对软件开发过程的约束。
    • 优先级:需求的优先级有助于在资源有限的情况下进行权衡,通常使用强制性、非常希望、希望和可选等固定点等级进行分类。
    • 范围:需求的范围指的是需求对软件及其组件的影响程度,某些非功能需求可能具有全局范围,影响多个组件的设计。

概念建模(Conceptual Modeling)

概念建模是软件需求分析中的一个关键活动,它涉及创建现实世界问题的模型,以帮助理解问题情境以及描述解决方案。概念模型包括问题域中的实体模型,这些实体被配置以反映它们在现实世界中的关系和依赖性。这一主题与软件工程模型与方法知识领域(Software Engineering Models and Methods KA)紧密相关。

概念建模可以开发的几种模型包括:

  • 用例图(Use case diagrams):常用于描述场景,其中边界将演员(用户或系统在外部环境中)与系统内部行为分开,每个用例描述系统的一个功能。

  • 数据流模型(Data flow models):展示系统中数据的流动和处理过程。

  • 状态模型(State models):描述系统或其组件可能处于的不同状态以及状态之间的转换。

  • 目标模型(Goal-based models):基于目标的模型,帮助识别和组织系统应该实现的目标。

  • 用户交互(User interactions):关注用户如何与系统交互。

  • 对象模型(Object models):使用面向对象的方法描述系统中的对象及其关系。

  • 数据模型(Data models):关注数据结构和数据库设计。

概念建模的影响因素包括:

  • 问题的性质:某些类型的软件可能需要特别关注某些方面的分析。例如,对于实时软件,状态和参数模型可能比信息系统更重要。

  • 软件工程师的专业知识:通常更有效地采用软件工程师有经验的建模符号或方法。

  • 客户的过程要求:客户可能偏好特定的符号或方法,或禁止使用他们不熟悉的符号或方法。

在几乎所有情况下,首先构建软件环境的模型是有用的。软件环境提供了软件与其外部环境之间的联系,这对于理解软件在操作环境中的上下文和识别其与环境的接口至关重要。

这一子主题不旨在“教授”特定的建模风格或符号,而是提供建模的目的和意图的指导。

架构设计与需求分配(Architectural Design and Requirements Allocation)

在软件需求分析的某个阶段,必须推导出解决方案的架构。架构设计是需求过程与软件或系统设计重叠的点,它说明了将这两个任务完全解耦是多么困难。这一主题与软件设计知识领域的软件结构和架构紧密相关。在许多情况下,软件工程师充当软件架构师,因为分析和详细说明需求的过程需要识别将负责满足需求的架构/设计组件。这就是需求分配——将需求分配给负责满足这些需求的架构组件。

需求分配的重要性在于它允许对需求进行详细分析。例如,一旦一组需求被分配给一个组件,就可以进一步分析这些单独的需求,以发现组件需要如何与其他组件交互以满足分配的需求。在大型项目中,分配会激发对每个子系统进行新一轮的分析。例如,对于汽车的特定制动性能的需求(制动距离、在恶劣驾驶条件下的安全、制动的平滑性、所需的踏板压力等)可能被分配给制动硬件(机械和液压组件)和防抱死制动系统(ABS)。只有当识别出对ABS的需求,并将需求分配给它时,才能使用ABS的功能、制动硬件的功能以及车辆重量等涌现属性来确定详细的ABS软件需求。

架构设计与概念建模紧密相关,因为它们都涉及到对软件的结构和行为的深入理解。在进行架构设计时,软件工程师需要考虑如何将需求映射到软件的各个部分,以及这些部分如何相互作用以实现整个系统的功能。这个过程通常涉及以下步骤:

  1. 需求理解:深入理解需求,以便能够合理地将它们分配给架构组件。
  2. 架构决策:基于需求和系统的质量属性(如性能、可靠性、可维护性等),做出关于软件架构的决策。
  3. 组件定义:定义系统中的组件,以及它们之间的接口和交互。
  4. 需求分配:将需求分配给特定的架构组件,确保每个需求都由适当的组件实现。
  5. 接口定义:明确组件之间的接口,确保它们能够正确地交互。
  6. 质量属性分析:分析架构设计如何影响系统的质量属性,并进行必要的调整。

架构设计和需求分配是软件工程中的创造性过程,需要软件设计师做出一系列基本决策,这些决策将深刻影响软件和开发过程。这个过程中的决策通常基于对质量属性的影响和竞争质量属性之间的权衡。

需求协商(Requirements Negotiation)

需求协商是解决利益相关者之间需求冲突的过程。在软件开发中,利益相关者可能会提出互相矛盾的需求,或者在功能需求与非功能需求之间存在冲突。有效的需求协商对于确保项目在预算、技术、监管和其他约束条件下满足主要利益相关者的需求至关重要。

以下是需求协商的几个关键点:

  1. 冲突识别
    • 在需求分析过程中,软件工程师需要识别不同利益相关者之间的需求冲突。这些冲突可能源于不同的优先级、资源限制或对软件功能的不同理解。
  2. 利益相关者参与
    • 需求协商通常需要所有相关利益相关者的参与,包括用户、客户、市场分析师和监管机构。通过集体讨论,利益相关者可以更清楚地表达各自的需求和期望。
  3. 协商技巧
    • 软件工程师在协商过程中需要运用有效的沟通技巧,确保所有利益相关者的观点都得到充分表达和理解。协商可能涉及妥协和权衡,以达到各方都能接受的解决方案。
  4. 优先级评估
    • 在协商过程中,软件工程师需要评估各个需求的优先级,以帮助确定哪些需求是必须满足的,哪些需求可以推迟或修改。这通常涉及到对需求的价值和成本进行分析。
  5. 记录和跟踪
    • 需求协商的结果应被记录并跟踪,以确保所有达成的共识和决策都能在后续的开发过程中得到遵循。这有助于保持需求的一致性和可追溯性。
  6. 变更管理
    • 需求协商还涉及变更管理,确保在项目进行过程中对需求的任何变更都经过适当的评估和批准。这有助于防止需求蔓延(scope creep)和确保项目按计划进行。

通过有效的需求协商,软件工程师能够在不同利益相关者之间建立共识,从而确保软件产品能够满足用户的实际需求和期望。这一过程不仅有助于提高软件的质量和用户满意度,还能减少后期的修改和返工,降低项目风险。

正式分析(Formal Analysis)

正式分析是需求分析过程中的一个重要环节,主要用于验证需求的正确性和一致性,确保软件在所有可能的条件下都能按预期运行。正式分析通常应用于高可靠性系统,尤其是在安全关键的应用中。以下是正式分析的几个关键点:

  1. 定义
    • 正式分析涉及使用具有严格数学基础的语言和符号来描述软件需求和设计。这种方法通过精确的语义定义来消除模糊性,从而确保需求的明确性和可验证性。
  2. 分析目标
    • 正式分析的主要目标是验证需求的完整性、一致性和正确性。通过对需求进行形式化表达,可以系统地检查需求是否满足预定的条件和约束。
  3. 工具支持
    • 正式分析通常依赖于特定的工具和技术,例如模型检查(model checking)和定理证明(theorem proving)。这些工具可以自动或半自动地验证软件模型的属性,确保其符合要求。
  4. 模型检查
    • 模型检查是一种形式化验证方法,通过对软件设计的状态空间进行探索,验证系统在所有可能的事件或消息到达顺序下的行为是否符合预期。模型检查能够提供对系统行为的全面分析,确保软件在各种条件下的可靠性。
  5. 预条件和后条件
    • 在正式分析中,软件工程师通常会为每个重要的功能或方法定义预条件(preconditions)和后条件(postconditions)。预条件是执行功能之前必须满足的条件,后条件是功能执行成功后保证成立的条件。这种方法有助于明确软件的行为和期望结果。
  6. 局限性
    • 尽管正式分析提供了强大的验证能力,但它的应用通常受到限制,主要是因为需要对软件进行严格的形式化建模,这在复杂系统中可能非常困难。此外,正式分析通常在需求和设计稳定后进行,因此在软件开发的早期阶段可能不适用。

通过正式分析,软件工程师能够在软件开发的早期阶段识别和修正潜在的问题,从而提高软件的质量和可靠性。这一过程对于安全关键系统尤为重要,因为它能够确保软件在面临各种条件时的正确性和稳定性。

需求规格说明(Requirements Specification)

需求规格说明是软件工程中一个关键的环节,它涉及创建一个系统化、可复审、可评估和可批准的文档,该文档详细描述了软件产品将要实现的功能和约束。这一过程确保了软件开发团队和客户之间对于软件产品预期的共同理解。以下是需求规格说明的关键点:

系统定义文档(System Definition Document):

  • 这个文档(有时也称为用户需求文档或概念操作文档)记录了系统需求。它从领域的角度定义了高层次的系统需求,内容包括系统目标环境、约束、假设和非功能需求的说明。系统定义文档可能包括用于阐释系统上下文的概念模型、使用场景和主要领域实体,以及工作流程。

系统需求规格说明(System Requirements Specification):

  • 对于包含大量软件和非软件组件的系统(例如现代飞机),系统需求通常从软件需求中分离出来。系统需求规格说明是一个系统工程活动,它定义了系统需求,然后从这些需求中派生出软件需求,并详细说明软件组件的需求。

软件需求规格说明(Software Requirements Specification):

  • 软件需求规格说明建立了客户和承包商或供应商(在市场驱动的项目中,这些角色可能由市场和开发部门扮演)之间关于软件产品将要做什么以及不期望做什么的协议基础。这一文档允许在设计开始之前对需求进行严格评估,减少后期的重新设计,为产品成本、风险和进度的估算提供现实基础,并作为开发有效的验证和验证计划的基础。

需求规格说明的质量指标包括:

  • 需求的明确性和可执行性。
  • 文档的完整性和一致性。
  • 需求的可测试性和可验证性。

需求规格说明通常使用自然语言编写,但也可以辅以正式或半正式的描述。选择合适的表示法可以更精确、简洁地描述需求,尤其是对于安全关键、监管和其他类型的可靠软件。


Similar Posts

Comments