软件工程 · 第 5 章

第 5 章 软件维护与度量

维护四类(完善性占比最大);可维护性三要素;McCabe 圈复杂度两种算法与完整例题;软件可靠性 MTTF/MTTR。

5.1 软件维护的四种类型(必背)

"哪种维护占比例最大"是高频选择题,答案很反直觉。

类型目的例子
改正性维护修复运行中发现的错误修复金额计算 Bug
适应性维护适应外部环境变化操作系统升级、数据库换版本后的改造
完善性维护增加新功能、优化性能加一个导出 Excel 功能
预防性维护主动改造打基础,防未来的坑重构难维护的模块
两个关键结论
  • 完善性维护占比最大(约一半)——用户永远想要更多功能,这没错。
  • 维护成本通常占软件生命周期总成本的 60% 以上,且年代越久占比越高。
易错
  • "修 Bug 是维护的主体"——错,改正性维护占比反而不大,完善性维护第一。
  • 预防性维护 = 主动出击;改正性维护 = 被动救火。方向别反。
课堂练习(3 题)
  1. 四种维护中占比最大的是哪一种? 答:完善性维护(增加功能、改进性能)。
  2. 因操作系统升级而修改软件,属于哪类维护? 答:适应性维护。
  3. 维护工作占软件总成本的比例大约是多少? 答:60% 以上(软件成本的大头在维护,不在开发)。

5.2 可维护性与维护成本

"什么样的软件好维护"——把因素列出来就能得分。

  • 可维护性:软件被理解、修改、扩充的容易程度。影响因素:
    • 可理解性(代码/文档是否清晰);
    • 可测试性(改完能不能快速验证);
    • 可修改性(模块化程度、耦合内聚的水平);
    • 可移植性、文档的完备程度。
  • 维护困难的技术原因:文档缺失、代码风格混乱、缺乏模块化(高耦合低内聚)、设计时没考虑扩展。
课堂练习(2 题)
  1. 哪三种性质构成"可维护性"的主要度量? 答:可理解性、可测试性、可修改性。
  2. 写代码时怎样做能让将来的维护成本更低? 答:模块化、高内聚低耦合、规范命名与注释、完善文档——这正是软件工程反复强调的。

5.3 McCabe 圈复杂度:会算就行 ★

McCabe 圈复杂度流图与三种算法
图 5-1 三种算法互相验算:边数−节点数+2 = 判定数+1 = 区域数

软考软件工程里唯一明确的"计算题",两个公式背下来。

圈复杂度 V(G) 的两种算法(结果相同,哪个方便用哪个):

公式一(按图形):V(G) = E − N + 2
    E = 流程图的边(箭头)数;N = 节点(圆圈)数

公式二(按判定):V(G) = 判定节点数 + 1
    判定节点 = 流程图里"分岔"的地方(条件判断)

含义:V(G) 等于"独立路径的条数"——要覆盖基本路径集,
     至少需要 V(G) 个测试用例。数字越大,程序越复杂、越难测试。
例题:手把手算一遍
某程序流程图:
  1 → 2(判断 A>0?)──真──→ 3 → 4
            └────假────→ 4
  4(判断 B=0?)───真───→ 5 → 6
            └────假────→ 6
  6(结束)

方法一:数节点与边
  节点:1,2,3,4,5,6 共 N = 6
  边:1→2, 2→3, 3→4, 2→4, 4→5, 5→6, 4→6 共 E = 7
  V(G) = E − N + 2 = 7 − 6 + 2 = 3

方法二:数判定点
  判定点:节点 2、节点 4,共 2 个
  V(G) = 2 + 1 = 3    ✓ 两法一致

结论:该程序圈复杂度为 3 → 至少设计 3 个用例覆盖独立路径。
易错
  • 公式一别漏"+2";节点、边都要数全(合流的地方容易漏边)。
  • 顺序结构(没有分岔)的程序 V(G) = 1,不是 0。
课堂练习(2 题)
  1. 流程图有 8 条边、7 个节点,圈复杂度是多少? 答:V(G) = 8 − 7 + 2 = 3。
  2. 一个函数里有 4 个 if 判断点,圈复杂度是多少? 答:V(G) = 4 + 1 = 5。

5.4 软件可靠性与其他度量

概念认识为主,软考偶有出现。

  • 软件可靠性——在规定条件下、规定时间内,软件不引起系统失效的能力。
  • MTTF(平均无故障时间)越长越可靠;MTTR(平均修复时间)越短越好——合起来影响可用性。
  • 软件复杂性度量:除 McCabe 圈复杂度外,还有代码行数、Halstead 度量等(了解名字)。
  • 可靠性 ≠ 正确性:正确性指"符合规格",可靠性指"持续符合规格的概率"。
课堂练习(2 题)
  1. MTTF 与 MTTR 分别是什么?哪个越大越好? 答:MTTF 是平均无故障时间(越大越好);MTTR 是平均修复时间(越小越好)。
  2. 软件可靠性与正确性的区别是什么? 答:正确性是"符合规格"的静态属性;可靠性是"一段时间内持续正常运行"的概率性属性。