软件维护和硬件维护有什么不同?
- 硬件维护的三项活动: 替换损坏的器件、清洁和润滑、修改设计上的缺陷;
- 硬件的修改多数是修复实现上的缺陷, 对用户常常不可见;
- 软件维护的内容: 不包括清洁、润滑和修复损坏器件, 主要是修复设计缺陷;
- 关键差异: 软件变更包含更多新增功能, 通常是用户能察觉的;
- 更广的定义: 维护由各种变更组成--修复设计缺陷、新增功能、使用环境或配置变换引起的调整;
维护成本有多高,受什么影响?
- 比例: 对一个广泛使用的程序, 维护总成本通常是开发成本的 40% 或更多;
- 用户数影响: 该成本受用户数目严重影响, 用户越多发现的错误越多;
- 生命周期曲线(Campbell): 新版本发布后, 上一版本被发现和修复的 bug 仍会出现, 新功能产生新 bug, 解决后正常运行几个月, 错误率随后重新攀升;
- 攀升原因: 用户使用到达新的熟练水平, 开始运用新功能, 高强度考验查出新功能中不易察觉的问题;
为什么缺陷修复会引入新 bug?
- 基本事实: 缺陷修复总会以 20%-50% 的机率引入新的 bug, 所以整个过程是"前进两步, 后退一步";
- 原因一(问题规模被低估): 看上去很轻微的错误, 实际可能是系统级别的问题, 通常不明显; 局部修复工作量清晰且不大, 更大范围的修复常被忽视, 除非软件结构简单或文档非常详细;
- 原因二(人员经验): 维护人员常常不是编写代码的开发人员, 而是初级程序员或新手;
- 降低手段: 使用能消除、至少能指明副作用的程序设计方法; 设计实现的人员越少、接口越少, 产生的错误也越少;
为什么必须回归测试?
- 逻辑: 引入新 bug 的后果是每条语句的维护需要比首次开发更多的系统测试;
- 理想要求: 每次修复之后必须重新运行先前所有测试用例, 确保系统不会以更隐蔽的方式被破坏;
- 现实: 回归测试必须接近上述理想状况, 所以成本非常高;
- 与阶段化的关系: 这正是变更必须阶段化、定期发布的原因之一(见 060-测试与集成);
系统的熵为什么会增加?
- 证据(Lehman 和 Belady): 研究大型操作系统一系列发布版本的历史, 发现模块数量随版本号线性增长, 但受到影响的模块以版本号指数级别增长;
- 结论一: 所有修改都倾向于破坏系统的架构, 增加系统的混乱程度;
- 结论二: 用在修复原有设计瑕疵上的工作量越来越少, 而早期维护活动本身漏洞引起的修复工作越来越多;
- 结局: 系统变得越来越无序, 修复工作迟早失去根基; 每一步前进都伴随着一步后退;
- 理论定位: 系统软件开发是减少混乱度(减少熵)的过程, 本身处于亚稳态;
- 软件维护是提高混乱度(增加熵)的过程, 即使最熟练的维护工作也只是放缓了系统退化到非稳态的进程;
- 实践推论: 崭新的、对原有系统的重新设计是完全必要的;