0%

第八章 维护

1. 维护的定义与持续时间

  • 定义:软件维护是指软件在交付使用之后,为了改正错误满足新的需要而修改软件的过程。这包括修复错误(bug)或增加新功能(如游戏更新、App更新)。
  • 持续时间:维护是软件开发过程中持续时间最长的阶段。它的时间定义是从软件交付之日到该软件最终被废弃为止。即使软件没有进行维护活动,但只要还在使用,就属于维护阶段。

2. 维护的四种类型

维护活动可以分为四种类型:

  • 改正性维护 (Corrective Maintenance / 改错性维护)
    • 定义:诊断和改正错误的过程。主要是修改bug。
    • 特点:比较常见。
  • 适应性维护 (Adaptive Maintenance)
    • 定义:为了和变化的环境适当配合而修改软件的过程。
    • 特点:是必要且经常的维护活动。例如,当硬件发展较快,软件需要更新以适配新硬件时。
  • 完善性维护 (Perfective Maintenance)
    • 定义:用户在使用软件过程中,提出增加新功能修改已有功能一般性改进建议而进行的维护。
    • 特点:通常占维护活动的大部分比重。主要是增加或增强功能。
  • 预防性维护 (Preventive Maintenance)
    • 定义:为了改进未来的可维护性、可靠性,或为未来的改进奠定更好的基础而修改软件时进行的维护。
    • 特点:目前所占比重较少。例如,在预定维护日期前整理文档资料或修改不适应的代码。

四类维护所占大致比重

  • 完善性维护:55% 至 66%
  • 改正性维护:约 20%
  • 适应性维护:约 20%
  • 预防性维护:约 4%

3. 软件维护的特点

  • 结构化维护与非结构化维护差别巨大

    • 非结构化维护:软件配置成分只有程序代码,文档、数据等缺失。这种软件维护起来非常困难,因为第一步就是难以读懂。
    • 结构化维护:存在完整的软件配置,从设计阶段开始的文档、图文资料都齐全。这种软件相对容易读懂和维护。
    • 主要区别在于文档是否齐全。
  • 维护的代价高昂

    • 金钱代价:最明显的体现在维护费用上。
    • 无形代价
      • 耽误甚至丧失开发的良机:可用资源必须供给维护使用,可能需要抽调正在开发新项目的人员去做维护,从而耽误新项目的开发。
      • 引起用户不满:当看起来合理的改错和修改要求不能及时满足时。
      • 降低软件质量:维护时的改动可能在软件中引入潜伏的错误。为避免这种情况,需要进行回归测试以防止非预期的副作用。
      • 造成开发过程混乱:软件工程师被突然调去从事维护工作,会造成工作交接和断档问题。
  • 维护问题很多

    • 根本原因:绝大多数问题都归因于软件定义和软件开发方法的缺点。通常是因为开发定义阶段没做好或文档资料不全。
    • 具体问题
      • 理解别人写的代码非常困难:尤其当软件配置成分减少(如仅有程序代码没有说明文档)时,困难程度迅速增加。
      • 软件缺乏合格的文档或文档资料显著不足。
      • 不能指望开发人员仔细说明:软件寿命长,原开发人员可能已离职或记不住细节。
      • 绝大多数软件在设计时没有考虑将来的修改:导致将来增加功能或扩充困难。
      • 软件维护不是一项吸引人的工作:因为维护工作可能很困难,需要反复论证和验证。

4. 软件维护过程

维护过程本质上是修改和压缩的软件定义和开发阶段。

  • 建立维护组织:通常不会成立专门的正式维护组织,而是指派原开发人员进行维护工作。
  • 确定维护报告和评价过程
    • 软件问题报告表:由用户提交,类似于报修流程。
    • 维护要求表:由维护人员编写,给出软件修改报告的必要信息,如所需工作量、维护性质和优先次序等。
  • 为每个维护规定一个标准化的事件流
    • 第一步确定要进行维护的类型(改错、改进或适应性维护)。
    • 若是改错型
      • 估算严重程度(优先级)。
      • 严重问题:立即开始工作。
      • 不严重问题:写入修正计划,等待统一修改。
    • 若是改进或适应性
      • 进行优先度评价
      • 严重的:立即开始做。
      • 低的:放到开发目录,等待统一修改。
    • 最后:进行复审。
  • 建立用于维护的保存过程和规定复审标准:收集每项维护工作的数据,如完成日期、开始日期、使用人员等,可构建数据库。
  • 评价维护活动:至少从七个方面对维护进行评价,包括每类维护活动的人员总数等。

5. 软件的可维护性

  • 定义:维护人员理解、改动、改进、改正软件的难易程度。也可指扩充和压缩的难易程度。
  • 决定软件可维护性的因素(及提高方法)
    • 可理解性 (Understandability)
      • 定义:外来读者理解软件结构、功能、接口和内部处理过程的难易程度。
      • 提高方法模块化详细的文档、结构化设计、程序的内部文档和良好的高级程序设计语言。
    • 可测试性 (Testability)
      • 定义:诊断和测试的容易程度,取决于软件的可理解程度。
      • 关系可理解性与可测试性相互促进
      • 提高方法:良好的文档、合理的软件结构、好用的测试工具和调试工具,以及良好的测试过程。
    • 可修改性 (Modifiability)
      • 影响因素耦合、内聚、信息隐蔽、局部化、控制与作用力的关系等。强调模块独立性
    • 可移植性 (Portability)
      • 定义:把程序从一个计算环境转移到另一个计算环境的难易程度。
      • 提高方法:将因环境变化而必须修改的程序局限在少数模块中
    • 可重用性 (Reusability)
      • 定义:同一个事物不做修改或稍加修改,在不同环境中多次重复使用。
      • 益处:大量使用重用构件可以提高可维护性,因为重用构件经过多次验证且节省人力。例如:类、类库。
    • 文档 (Documentation)
      • 决定因素:文档是影响软件可维护性的决定因素
      • 两类文档
        • 用户文档:主要描述系统功能和使用方法。
        • 系统文档:如软件可行性报告、需求规格说明书等用户不关心但开发人员需要的资料。

6. 预防性维护的方法:软件再工程 (Software Re-engineering)

软件再工程是预防性维护的一种方法。

  • 预防性维护的几种做法

    1. 反复多次尝试修改程序,与源代码“顽强战斗” (不推荐)。
    2. 通过仔细分析程序员,尽可能多地掌握内部细节以有效修改。
    3. 在深入理解原有设计的基础上,用软件工程方法重新设计、编码、测试那些需要变更的部分 (部分再工程)。
    4. 使用软件工具和方法学为指导,对程序进行全部重新设计、编码和测试 (完整再工程,使用CASE工具等)。
  • 软件再工程的工作内容

    • 库存目录分析 (Inventory Analysis)
      • 分析应用系统的基本信息(如年份、用户量、规模、修改次数、业务重要程度等)。
      • 识别预防性维护(再工程)的对象
        • 预定要使用很多年的程序。
        • 当前正在成功使用的系统/程序。
        • 近期内具有重大修改或增强的程序。
    • 文档重构 (Document Restructuring)
      • 老程序固有特点是文档资料缺失。文档重构非常耗时。
      • 策略
        • 保持现状:如果软件即将废弃,没必要重构文档。
        • 部分重构:只针对系统当前正在修改的部分建立文档,随时间推移逐渐攒齐。
        • 完整重构:针对业务关键系统,仍然需设法压缩工作量进行全面文档重构。
    • 逆向工程 (Reverse Engineering)
      • 定义:分析程序,以便在比源代码更高的抽象层次上创建程序的某种表示过程。
      • 目的恢复设计结果。工具从现有程序中抽取有关数据、体系结构和处理过程的设计信息。
    • 代码重构 (Code Restructuring)
      • 描述:最常见的再工程活动。适用于体系结构完整但个体编码方式较差的老程序。
      • 做法:用重构工具分析源代码,标注违背结构化程序概念的部分,重构有问题代码,复审测试重构代码并更新文档。
    • 数据重构 (Data Re-engineering):发生在较低抽象层次上的全范围再工程活动。
    • 正向工程 (Forward Engineering) / 革新或改造 (Renovation or Re-adaptation)
      • 定义:不仅从现有程序中恢复设计信息,而且用该信息去改编或重构现有系统。
      • 目的:提高整体质量。