软件生存期模型

(第一部分:软件工程概述,第2章)

李欣

Created: 2022-04-06 Wed 00:52

0.1. 互动课堂

Click to host the seminar.


0.2. 本次课的目标

第一部分:软件工程概述

第2章:软件生存期模型

  • 瀑布模型
  • 快速原型模型
  • 增量模型
  • 螺旋模型
  • 喷泉模型
  • 统一过程
  • 基于构件的开发模型
  • 敏捷过程

0.3. 软件生存期模型

软件生存期模型 也称为 软件过程模型 , 是从 软件项目需求定义 直至 软件运行维护 为止, 跨越整个生命周期的系统开发、运行和维护所实施的全部过程活动和任务的结构框架 。 到目前位置,已经提出了多种软件生存期模型, 典型的包括 瀑布模型原型模型增量模型螺旋模型统一过程敏捷过程 等。

1. 瀑布模型

在20世纪80年代之前, 瀑布模型 一直是唯一被广泛采用的 软件生存期模型传统软件工程方法学软件过程 基本上可以用 瀑布模型 来描述。

1.1. 传统的瀑布模型

waterfall-model-classic.png

传统瀑布模型的特点:

  • 阶段间具有 顺序性依赖性
    1. 必须等 前一阶段 的工作完成后才能开始 后一阶段 工作
    2. 前一阶段的 输出文档 就是后一阶段的 输入文档
  • 推迟实现 的观点
    1. 系统分析系统设计 阶段的基本任务规定主要考虑目标系统的 逻辑模型
    2. 清楚地区分 逻辑设计物理设计 ,尽可能推迟程序的物理实现
  • 质量保证 的观点
    1. 每个阶段都必须完成规定的 文档
    2. 每个阶段结束前都要对所完成的文档进行 评审

1.2. 实际的瀑布模型

waterfall-model-actual.png

实际瀑布模型的特点:

  • 反馈环 ,实线箭头表示开发过程,虚线箭头表示维护过程
  • 后面阶段发现前面阶段的错误时,需要沿反馈线返回前面阶段, 修正 后再继续后面阶段的任务

1.3. V模型

v-model.png

经典生存期模型V模型 没有本质区别, V模型 提供了一种将 测试活动应用于早期软件工程工作中的方法

1.4. 瀑布模型优缺点

瀑布模型优点

  • 可强迫开发人员采用 规范化 的方法
  • 严格地规定了每个阶段必须提交的 文档
  • 要求每个阶段交出的所有产品都必须是经过 验证(评审)

瀑布模型缺点

  • 需求规格说明与用户需求之间有差异 ,会导致开发的软件产品 不能 真正满足用户需要
  • 瀑布模型只适用于项目开始时 需求已确定的情况

2. 快速原型模型

快速原型 是快速建立起来的可以在计算机上运行的程序, 它所能完成的功能往往是

最终产品功能的一个子集

rapid-prototyping-model.png

2.1. 快速原型模型的优点

  • 有助于满足用户的 真实需求
  • 原型系统已经通过与用户的交互而得到 验证 ,产生的规格说明文档能够正确地描述用户需求
  • 软件产品的开发基本上是按 线性顺序 进行
  • 因规格说明文档正确描述了用户需求,后续开发过程 不会进行较大返工
  • 开发人员通过建立原型系统已经学到很多东西,因此,在设计和编码阶段 发生错误的可能性比较小
  • 快速原型的本质是 快速 ,一旦需求确定,便可抛弃原型或在原型的基础上进行开发

3. 增量模型

增量模型 也称为 渐增模型 ,是Mills等人于1980年提出来的。 使用增量模型开发软件时,把软件产品作为一系列的 增量构件设计编码集成测试 。 每个构件由多个相互作用的模块构成,并且能够完成特定的功能。

例如,使用增量模型开发字处理软件时,

  • 第一个增量构件提供 最基本的文件管理、编辑和文档生成 功能;
  • 第二个增量构件提供 更完善的编辑和文档生成 功能;
  • 第三个增量构件实现 拼写和语法检查 功能;
  • 第四个增量构件完成 高级的页面排版 功能。

incremental-model.png

增量模型的优点:

  • 能够在 较短的时间 内向用户提交一些有用的工作产品
  • 逐步增加产品的功能可以使用户有较 充裕的时间 学习和适应新产品
  • 项目 失败的风险较低 ,某些增量构件遇到问题时仍有可交付给用户的其他增量构件
  • 优先级最高的服务首先交付,然后将其他构件逐次集成进来,可 保证最重要的系统服务 接受最多的测试

3.1. 增量构件开发

incremental-development.png

软件产品 分解成一系列的 增量构件 ,在 增量开发迭代 中逐步加入。 为此,要求构件的 规模适中 ,并且新构件集成到已有软件所形成的新产品必须是 可测试 的。

3.2. 采用增量模型的注意事项

  • 在把每个新的增量构件集成到现有软件体系结构中时, 必须不破坏已经开发出来的产品
  • 软件体系结构必须是开放的,即 向现有产品中加入新构件的过程必须简单、方便

因此,采用 增量模型 比采用 瀑布模型快速原型模型 更需要 精心的设计

4. 螺旋模型

螺旋模型 最初是Boehm于1988年提出来的。 该模型将 瀑布模型快速原型模型 结合起来, 并且加入两种模型均忽略了的 风险分析

4.1. 简化的螺旋模型

螺旋模型的基本思想是, 使用原型及其他方法来尽量降低风险。 理解这种模型的一个简便方法, 是把它看作 在每个阶段之前都增加了 风险分析过程 的快速原型模型

spiral-model-lite.png

4.2. 完整的螺旋模型

spiral-model-full.png

4.3. 螺旋模型解读

在螺旋模型中,软件过程表示成一个螺线, 而不是像以往的模型那样表示为一个具有回溯的活动序列。 在螺线上的 每一个循环 表示 过程的一个阶段

  • 每个阶段 开始时的任务是确定该阶段的目标 、 为完成这些目标 选择方案及设定这些方案的约束条件
  • 接下来的任务是, 从风险角度分析上一步的工作结果 , 努力排除各种潜在的风险,通常 用建造原型的方法来排除风险
  • 如果成功地排除了所有风险,则启动下一步 开发步骤 , 在这个步骤的工作过程相当于 纯粹的瀑布模型
  • 最后是 评价 该阶段的工作成果并 计划下一个阶段的工作

螺线上的每一个循环可划分为 4个象限 ,分别表达了 4个方面的活动

  1. 目标设定 : 定义在该阶段的 目标 ,弄清对过程和产品的 限制条件 , 制订详细的 管理计划 ,识别 项目风险 ,可能还要计划与这些风险有关的 对策
  2. 风险估计与弱化针对每一个风险进行详细分析 ,设想 弱化风险的步骤
  3. 开发与验证评价风险 之后 选择系统开发模型
  4. 计划 : 评价开发工作,确定是否继续进行螺线的下一个循环。 如果确定要继续,则 计划项目的下一个阶段的工作

4.4. 螺旋模型优缺点

螺旋模型优点

  • 对可选方案和约束条件的强调 有利于已有软件的重用 , 也 有助于把软件质量作为软件开发的一个重要目标
  • 减少 了过多测试或测试不足所带来的 风险
  • 在螺旋模型中维护只是模型的另一个周期, 因而在 维护和开发之间并没有本质区别

螺旋模型缺点

  • 螺旋模型是 风险驱动 的, 因此要求软件开发人员必须具有丰富的 风险评估经验 和这方面的专门知识, 否则将出现真正的风险—当项目实际上正在走向灾难时,开发人员可能还以为一切正常。

5. 喷泉模型

喷泉模型 是典型的面向对象生命周期模型。 “喷泉”一词体现了 迭代无间隙 特性。 图中代表不同阶段的圆圈相互重叠, 这表示 两个活动之间存在重叠

fountain-model.png

6. 统一过程

20世纪90年代早期,Grady Booch、Ivar Jacobson和James Rumbaugh开始研究 统一方法 , 他们的成果就是统一建模语言UML(Unified Modeling Language)。 UML提供了支持 面向对象软件工程实践 必要的技术, 但它 没有 提供 指导项目团队应用该技术时的过程框架

UML是一种语言,并不是方法论。

Booch、Jacobson及Rumbaugh接下来的努力是发布完全、统一的面向对象分析与设计的方法学, 这种统一的方法学最初称为Rational统一过程(Rational Unified Process, RUP), 为简洁起见,使用 统一过程 这个术语。 统一过程用UML进行面向对象软件工程的框架 。 目前, 统一过程UML 广泛应用在各种各样的面向对象项目中。

6.1. 统一过程模型

rup.png

尽管6个核心过程工作流可能使人想起传统瀑布模型中的几个阶段, 但应注意迭代过程中的阶段是完全不同的, 这些工作流在整个生命周期中一次又一次被访问。 9个核心工作流在项目中轮流被使用, 在每一次迭代中以不同的重点和强度重复。

6.2. 统一过程的核心过程工作流

统一过程中有6个 核心过程工作流(Core Process Workflows)

  • 业务建模(Business Modeling)工作流 : 用 业务用例业务过程 建立模型。
  • 需求(Requirements)工作流 : 描述系统应该做什么,确保开发人员构建正确的系统。 为此,需明确系统的 功能需求非功能需求(约束)
  • 分析与设计(Analysis & Design)工作流 : 分析和细化需求,并建立 分析模型设计模型
  • 实现(Implementation)工作流 : 用选择的实现语言实现目标系统。 以 分层 的方式 组织代码的结构 ,用 构件 的形式来 实现类 , 对构件进行 单元测试 ,将 构件集成 到可执行的系统中。
  • 测试(Test)工作流 : 执行 集成测试验证对象之间的交互 , 是否所有的构件都集成了,是否正确实现了所有需求,查错并改正。 测试类似于三维模型,分别从 可靠性功能性系统性能 这三个维度来进行。
  • 部署(Deployment)工作流 : 制作软件的外部版本,软件 打包分发 ,为用户提供 帮助和支持

6.3. 统一过程的核心支持工作流

统一过程中有3个 核心支持工作流(Core Supporting Workflows)

  • 配置与变更管理(Configuration & Change Management)工作流 : 描绘如何在多个成员组成的项目中 控制大量的产物 , 如何 管理并行开发、分布式开发 ,如何 自动化创建工程 , 以及如何管理产品的 修改原因时间人员审计记录
  • 项目管理(Project Management)工作流平衡各种可能产生冲突的目标管理风险克服各种约束成功交付 可使用户满意的产品。 其目标包括:为 项目的管理 提供框架, 为 计划人员配备执行监控项目 提供实用的准则, 为 管理风险 提供框架等。
  • 环境(Environment)工作流 : 向软件开发组织提供 软件开发环境 ,包括 过程工具 。 环境工作流集中于 配置项目过程中所需要的活动 , 同样也 支持开发项目规范的活动 , 提供了 逐步的指导手册 并介绍如何在组织中实现过程。

6.4. 统一过程的阶段

统一过程有4个阶段,均以 里程碑 结束。 里程碑 的意图是捕捉 项目生命周期中的点 , 在这些点上可能进行重大的 管理决策进展评估

  • 初始阶段 关注 项目计划和风险评估 ,确定是否值得开发目标系统,回答下面问题
    1. 目标系统是否是 经济的
    2. 目标系统是否能 按期交付
    3. 开发系统所涉及的 风险 是什么?
  • 细化阶段 关心 定义系统的总体框架 ,有下面几个目标
    1. 细化 初始需求
    2. 细化 体系结构
    3. 监控风险细化它们的优先级
    4. 细化 业务用例 以及制定 项目管理计划
  • 构造(构建)阶段 是建立系统的第一个 具有操作性的版本 , 以能够交付给客户进行测试的版本结束,有时称为测试版本
  • 移交阶段 以发布 完整的系统 而终止,其目标是确保系统真正满足客户的需求

7. 基于构件的开发模型

基于构件的开发 是利用预先包装的 构件 来构造应用系统。 构件可以是 组织内部开发的 ,也可以是现有的 商业成品构件(Commercial Off-The-Shelf, COTS)

基于构件的软件工程(Component-Based Software Engineering, CBSE) 强调使用可复用的软件 构件 来设计和构造基于计算机的系统。

通常来讲, 构件 是计算机软件中的一个模块化的构造块。

7.1. 构件的定义

OMG(Object Management Group)统一建模语言规范是这样定义构件的,

系统中 模块化的可部署的可替换的 部件, 该部件 封装了实现暴露一系列接口

— Object Management Group

国际上第一本软件构件专著 《构件化软件—超越面向对象编程》(Szyperski) 给出的构件定义是,

一个构件是一个组装单元,它具有约定式规范的接口,以及明确的依赖环境。 构件可以被独立部署,由第三方组装。

7.2. 基于构件的开发模型图

component-based-development.png

7.3. 基于构件的软件工程开发思路

CBSE软件团队针对每一系统需求并不急于进行设计,而是询问如下问题。

  • 现有的商业成品构件 是否能够实现该需求?
  • 内部开发的可复用构件 是否能够实现该需求?
  • 可用构件的接口 与待构造系统的体系结构是否相容?

团队可以试图 修改去除 那些不能用 COTS自有构件 实现的系统需求。 如果不能 修改去除 这些需求,则必须 应用软件工程方法构造满足这些需求的新构件

7.4. 基于构件的软件工程开发步骤

基于构件的开发模型中, 需求分析和设计建模活动 开始于 识别可选构件 , 这些构件有些设计成 通用的软件模块 ,有些设计成 面向对象的类或软件包 。 不考虑构件的开发技术, 基于构建的开发模型 由以下步骤组成。

  • 对该问题领域的 基于构件的可用产品 进行 研究和评估
  • 考虑构件集成 的问题
  • 设计软件体系结构(或称架构) 以容纳这些构件
  • 将构件 集成到体系结构
  • 进行充分的测试 以保证功能正常

7.5. 基于构件的开发模型的好处

软件复用是提高 软件生产率软件质量 的最有效的途径, 而 基于构件的软件开发面向对象的软件开发 实现了 更大粒度软件复用 , 能够 最大限度减少重复劳动缩短开发周期降低开发成本 , 从而使 软件生产率 得到提高。

由于已有的构件大都经过了很长时间的运行和测试,在 质量方面比新开发的软件更有保证 , 同时软件构件技术有助于 软件设计的标准化设计风格的改进与统一 , 进而提高系统间的互操作性, 软件可靠性可维护性 可以得到增强。

构件技术的研究和实践,能够积累和共享相关知识,使软件在 灵活性标准化 等方面均得到改善, 有助于实现软件开发的 工程化工业化产业化

8. 敏捷过程

2001年,以Kent Beck为首的敏捷联盟发表了 敏捷软件开发 宣言。

我们正在通过亲身实践以及帮助他人实践的方式来揭示更好的软件开发之路, 通过这项工作,我们认为:

  • 个体和交互 胜过 过程和工具
  • 可工作软件 胜过 宽泛的文档
  • 客户合作 胜过 合同谈判
  • 响应变更 胜过 遵循计划

也就是说,虽然上述内容中右边的各项很有价值, 但我们认为左边的各项具有更大的价值。

8.1. 什么是敏捷

Ivar Jacobson给出以下论述:

敏捷团队是能够适当相应变更的灵活团队。 变更就是软件开发本身, 软件构建过程 有变更、 团队成员 在变更、使用新 技术 会带来变更, 各种变更都会对开发的软件产品以及项目本身造成影响。 我们必须接受 支持变更 的思想, 它应当根植于软件开发中的每一件事中, 因为它是软件的心脏与灵魂。

敏捷团队意识到软件是团队中所有人 共同 开发完成的, 这些人的 个人技能合作能力 是项目成功的关键所在。

在Jacobson看来, 普遍存在的变更是敏捷的基本动力 , 软件工程师必须加快步伐以适应Jacobson所描述的快速变更。

8.2. 敏捷方法适用的项目

从本质上讲,敏捷方法是 为了克服传统软件工程中认识和实践的弱点 而形成的。 敏捷开发 可以带来多方面的好处 ,但它并 不适用于所有项目及产品 。 一般来说,敏捷方法更适合具有 以下特征 的软件开发项目。

  • 提前预测 哪些需求是稳定的哪些需求会变更 非常困难。 同样的,预测项目进行中 客户优先级的变更 也很困难。
  • 对很多软件,设计和构建是交错进行的。 事实上,两种活动应当顺序开展以保证通过构建来验证设计模型, 而在通过构建验证之前很难估计 应该设计到什么程度
  • 从制定计划的角度来看, 分析设计构建测试 并不像我们所设想的那么容易预测。

8.3. 敏捷原则

敏捷联盟定义了以下12条敏捷原则:

  1. 我们最优先要做的是通过尽早、持续地交付有价值的软件来使客户满意。
  2. 即使在开发的后期,也欢迎需求变更。敏捷过程利用变更为客户创造竞争优势。
  3. 经常交付可运行软件,交付的间隔可以从几个星期到几个月,交付的时间间隔越短越好。
  4. 在整个项目开发期间,业务人员和开发人员必须天天都在一起工作。
  5. 围绕有积极性的个体构建项目,给他们提供所需的环境和支持,并且信任他们能够完成工作。
  6. 在团队内部,最富有效果和效率的信息传递方法是面对面交谈。
  7. 可运行软件是进度的首要度量标准。
  8. 敏捷过程提倡可持续的开发速度。责任人(Sponsor)、开发者和用户应该能够长期保持稳定的开发速度。
  9. 不断地关注优秀的技能和好的设计会增强敏捷能力。
  10. 简单—使不必做的工作最大化的艺术—是必要的。
  11. 最好的架构、需求和设计出自于自组织团队。
  12. 每隔一定时间,团队会反省如何才能更有效地工作,并相应调整自己的行为。

并不是每一个敏捷模型都同等使用这12项原则,一些模型可以选择忽略或淡化一个或多个原则的重要性。

8.4. 极限编程

极限编程(eXtreme Programming, XP)使用最广泛的敏捷过程 , 其相关思想和方法最早出现于20世纪80年代后期, 但直到2000年Kent Beck撰写的《Extreme Programming Explained: Embrace Change》一书出版, 它才引起软件业的极大关注。

XP使用 面向对象方法 作为推荐的开发范型, 它包含了 策划设计编码测试 4个框架活动的规则和实践。

  • 策划

    策划活动 属于 需求获取活动 , 通过 倾听用户对软件需求的一系列描述 (主要为功能描述,也成为 用户故事 ), 使XP团队成员理解软件的 商业背景 以及 要求的输出主要特征主要功能

    客户XP团队 共同决定 如何把故事分组 ,并置于XP团队将要开发的下一个发行版本中。 一旦认可对下一个发行版本的基本承诺(包括故事、交付日期和其他项目事项), XP团队将按以下三种方式之一对 待开发的故事 进行排序:

    1. 所有选定故事 将在几周之内 尽快实现
    2. 具有 最高价值的故事 将移到进度表的前面并 首先实现
    3. 高风险的故事首先实现

    项目的第一个发行版本交付之后, XP团队计算 项目的速度 ,即 第一个发行版本实现的用户故事个数 , 帮助建立 后续发行版本发布日期进度安排 , 确定 是否对整个开发项目中的所有故事有过分承诺 。 一旦发生过分承诺,则 调整软件发行版本的内容 或者 改变最终交付日期

  • 设计

    XP设计 严格遵循保持简洁(Keep It Simple, KIS)原则, 使用 简单而不是复杂 的表述。 另外,设计为故事提供 不多也不少的实现原则 , 不鼓励额外功能性(开发者假定以后会用到)的设计。

    XP的中心思想 使设计可以在编码开始前后同时进行 , 重构意味着 设计随着系统的构建而连续进行 。 实际上,构建活动本身将给XP团队 提供关于如何改进设计的指导

  • 编码

    XP推荐在故事开发和初步设计完成之后 不应直接开始编码 , 而是开发一系列用于检测本次(软件增量)发布的包括 所有故事的单元测试 。 一旦建立了单元测试,开发者就可以把精力更集中于 必须实现的内容 ,以通过单元测试。 不需要加任何额外的东西(保持简洁)。 一旦编码完成,就可以立即完成单元测试,从而向开发者提供 即时的反馈

    XP编码活动中的关键概念之一是 结对编程 。 XP推荐两个人面对同一台计算机 共同为一个故事开发代码 。 这一方案提供 实时解决问题实时质量保证机制 , 同时也使 开发者能集中精力解决当前的问题 。 实施中 不同成员担任的角色略有不同

  • 测试

    在编码开始之前 建立单元测试 是XP方法的关键因素。 所建立的单元测试应当 使用一个可以自动实施的框架 , 因此 易于执行并可重复 ,这种方式支持 代码修改之后及时的回归测试策略

    一旦将 个人的单元测试 组织到一个 通用测试集 , 就可以每天进行 系统的集成和确认测试 , 这可以为XP团队提供 连续的进展指示 , 也可在 一旦发生问题的时候及早提出预警

8.5. 其他敏捷过程模型

敏捷过程模型中除了适用最广泛的XP,还有许多其他敏捷过程模型,它们也在行业中使用。 较普遍的有自适应软件开发(ASD)、Scrum、敏捷建模(AM)、敏捷统一过程(AUP)等。

  • 自适应软件开发(Adaptive Software Development, ASD) 是由Jim Highsmith提出的, 它可作为构建复杂软件和系统的一项技术,其基本概念着眼于 人员协作团队自我组织 。 生命周期包含 思考协作学习 三个阶段。
  • Scrum 得名于橄榄球比赛,其原则于敏捷宣言一致,同时强调使用一组 软件过程模式 , 这些过程模式被证实在 时间紧张的需求变化的业务关键的 项目中是有效的。 包含 待定项(backlog)冲刺(sprint)Scrum例会演示
  • 敏捷建模(Agile Modeling, AM) 原则中独具特色的内容是 有目的的模型使用多个模型轻装上阵理解模型及工具适应本地需要
  • 敏捷统一过程(Agile Unified Process, AUP) 采用 在全局连续在局部迭代 的原理来构建基于计算机的系统。 每个AUP迭代执行的活动包括 建模实现测试部署配置及项目管理环境管理

9. 课后作业

  1. 瀑布模型、快速原型模型、增量模型及螺旋模型都是传统的软件过程模型, 请给出各个模型的特点。每种模型的优点和缺点是什么?适用于哪些场合?(习题2.1)
  2. 可以合用几种模型吗?如果可以,举例说明。(习题2.3)
  3. 解释喷泉模型的特点及其适用的场合。(习题2.4)
  4. 统一过程的4个阶段是什么?(习题2.8)
  5. 简述敏捷软件开发的原则。(习题2.11)