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):
- 决定因素:文档是影响软件可维护性的决定因素。
- 两类文档:
- 用户文档:主要描述系统功能和使用方法。
- 系统文档:如软件可行性报告、需求规格说明书等用户不关心但开发人员需要的资料。
- 可理解性 (Understandability):
6. 预防性维护的方法:软件再工程 (Software Re-engineering)
软件再工程是预防性维护的一种方法。
预防性维护的几种做法:
- 反复多次尝试修改程序,与源代码“顽强战斗” (不推荐)。
- 通过仔细分析程序员,尽可能多地掌握内部细节以有效修改。
- 在深入理解原有设计的基础上,用软件工程方法重新设计、编码、测试那些需要变更的部分 (部分再工程)。
- 使用软件工具和方法学为指导,对程序进行全部重新设计、编码和测试 (完整再工程,使用CASE工具等)。
软件再工程的工作内容:
- 库存目录分析 (Inventory Analysis):
- 分析应用系统的基本信息(如年份、用户量、规模、修改次数、业务重要程度等)。
- 识别预防性维护(再工程)的对象:
- 预定要使用很多年的程序。
- 当前正在成功使用的系统/程序。
- 近期内具有重大修改或增强的程序。
- 文档重构 (Document Restructuring):
- 老程序固有特点是文档资料缺失。文档重构非常耗时。
- 策略:
- 保持现状:如果软件即将废弃,没必要重构文档。
- 部分重构:只针对系统当前正在修改的部分建立文档,随时间推移逐渐攒齐。
- 完整重构:针对业务关键系统,仍然需设法压缩工作量进行全面文档重构。
- 逆向工程 (Reverse Engineering):
- 定义:分析程序,以便在比源代码更高的抽象层次上创建程序的某种表示过程。
- 目的:恢复设计结果。工具从现有程序中抽取有关数据、体系结构和处理过程的设计信息。
- 代码重构 (Code Restructuring):
- 描述:最常见的再工程活动。适用于体系结构完整但个体编码方式较差的老程序。
- 做法:用重构工具分析源代码,标注违背结构化程序概念的部分,重构有问题代码,复审测试重构代码并更新文档。
- 数据重构 (Data Re-engineering):发生在较低抽象层次上的全范围再工程活动。
- 正向工程 (Forward Engineering) / 革新或改造 (Renovation or Re-adaptation):
- 定义:不仅从现有程序中恢复设计信息,而且用该信息去改编或重构现有系统。
- 目的:提高整体质量。
- 库存目录分析 (Inventory Analysis):