SE-06 软件质量与维护
06 · 软件质量与维护(Software Quality & Maintenance)
📅 预计 45 分钟 | ⭐ = 核心概念 | 📌 中英术语见文末
✍️ 配套练习:课程中心「软件工程」模块在线测验
6.1 什么是软件质量:不只是"没 bug"
好软件像好冰箱,不响、省电、耐用
"质量"听着抽象,举个例子就清楚了:一台冰箱,制冷正常只算基本要求;它安静(性能)、省电(效率)、十年不坏(可靠性)、坏了容易修(可维护)、说明书一看就懂(可用性),才算高质量。软件质量同理——软件满足规定需求和用户隐含期望的程度。
软件质量有个残酷现实:缺陷发现得越晚,修复成本越高(需求阶段 1 倍成本,到运行阶段可能是几十上百倍)。所以质量不是测试阶段才管,而是贯穿需求、设计、编码、测试全过程的工程责任。
💡 记忆口诀:质量 = 功能正确 + 质量属性达标 + 用户满意。质量是"造"出来的,不是"测"出来的。
⚠️ 常见错误
- 把"质量"等同于"没有 bug":功能正确只是起点,性能、安全、可维护、易用都算质量。
- 以为质量是测试员的事:从需求到编码每个环节都在决定最终质量,缺陷发现越晚越贵。
6.2 软件质量模型:给"好"定出可衡量的标准 ⭐
没有标准,就无法度量;无法度量,就无法改进
"好用"不能直接测,所以要质量模型把"好"拆成一棵可以逐个打分的属性树。两个经典模型:
① McCall 质量模型(三个视角)
| 视角 | 关注 | 典型属性 |
|---|---|---|
| 产品运行 | 软件跑起来怎么样 | 正确性、可靠性、效率、完整性(安全)、可用性 |
| 产品修正 | 改起来方不方便 | 可维护性、灵活性、可测试性 |
| 产品转移 | 换环境行不行 | 可移植性、可复用性、互操作性 |
② ISO/IEC 9126(2001)与后续的 ISO/IEC 25010(更常用)
ISO 9126 分六大特性,每个特性下有子特性:
| 特性 | 通俗理解 | 子特性举例 |
|---|---|---|
| 功能性 | 该有的功能有没有、对不对 | 适合性、准确性、互操作性、安全性 |
| 可靠性 | 稳不稳、容不容易坏 | 成熟性、容错性、易恢复性 |
| 易用性 | 用户好不好上手 | 易理解、易学习、易操作 |
| 效率 | 资源用得多不多 | 时间特性、资源特性 |
| 可维护性 | 改起来难不难 | 易分析、易改变、易测试、稳定性 |
| 可移植性 | 换平台行不行 | 适应性、易安装、共存性 |
后续的 ISO 25010 把"安全性""兼容性"单独立为顶层特性,方向更面向现代软件。
质量模型的价值:把抽象的"高质量"变成一组可打分、可测试的指标,让质量从口号变成工程。
质量保证(SQA)与质量控制(QC):一个"防",一个"查"
质量模型给出"测什么",还需要管理手段让质量落地。两个常被混淆的概念:
| 概念 | 英文 | 做什么 | 类比 |
|---|---|---|---|
| 质量保证 | SQA(Software Quality Assurance) | 过程层面的预防:审查流程、规范、评审是否执行,防止缺陷产生 | 制定并检查施工规范 |
| 质量控制 | QC(Quality Control) | 产品层面的检查:通过测试、审查找出并消除缺陷 | 逐件质检成品 |
一句话:SQA 管过程(防患于未然),QC 管结果(找出并消灭问题)。SQA 是"确保会做对",QC 是"检查做没做对"。
⚠️ 常见错误
- 把特性与子特性记混:如"可靠性"是顶层特性,"容错性"是它的子特性。
- 只背六大特性不看内涵:出题常给"系统崩溃后能恢复",问属于哪个特性——答案落在可靠性的子特性"易恢复性"。
6.3 软件维护:交付不是终点,是起点 ⭐
上线之后,软件才真正开始"生活"
很多项目交付即"毕业",但现实中维护阶段往往占软件总成本的一半以上。软件维护(maintenance)指软件交付后,为修正问题、适应环境、改进功能而进行的修改活动。维护分四类 ⭐:
| 类型 | 干什么 | 例子 |
|---|---|---|
| 改正性维护(corrective) | 修复发现的 bug | 修复登录闪退 |
| 适应性维护(adaptive) | 应对外部环境变化 | 升级操作系统版本、适配新浏览器 |
| 完善性维护(perfective) | 新增/改进功能提升体验 | 增加"一键导出报表" |
| 预防性维护(preventive) | 防止未来出问题、改善可维护性 | 重构晦涩代码、补充注释、优化架构 |
数据事实:各类维护中,完善性维护占比最高(约一半),改正性维护其实占比不大——这正好印证"需求一直在演化,软件一直在生长"。
"软件维护难"的根本原因:文档缺失、代码可读性差、模块耦合高、人员流动后知识断层——这些问题在设计和编码阶段的偷懒,最终都靠维护阶段加倍偿还。
💡 记忆口诀:维护四类 = 修(改正)、适(适应)、善(完善)、防(预防)。占比:完善 > 改正,别记反。
⚠️ 常见错误
- 记混四类维护:加新功能 = 完善性,不是适应性;适配新系统 = 适应性;修 bug = 改正性;重构防患 = 预防性。
- 以为维护只是"改改小毛病":维护涵盖功能演进与结构调整,成本常超开发。
- 忽略维护占比:维护成本通常超过开发成本,是软件总成本的大头。
6.4 配置管理:给软件的"零部件"上保险 ⭐
没有配置管理,改着改着就"乱套"了
假设多人协作开发,A 改了一个文件,B 也在改同一个文件,两人都觉得自己是对的——最终版本是谁的?需求文档、代码、数据库脚本、配置文件散落各处,怎么保证"当前线上跑的"和"最新代码"是一套?配置管理(configuration management, CM)就是解决这套"乱套"问题的管理技术。
配置项(configuration item):软件开发过程中需要受控管理的对象,包括源代码、文档、配置文件、构建脚本、数据库脚本、可执行程序等。
配置管理的核心活动 ⭐:
| 活动 | 作用 | 关键概念 |
|---|---|---|
| 版本控制 | 每个文件每个版本留痕,可回溯 | Git 提交、分支、标签 |
| 变更控制 | 修改不随意,走审批流程 | 变更请求 CCB(变更控制委员会) |
| 配置审计 | 定期核对"该有的配置项都在且一致" | 防止配置项丢失 |
| 基线管理 | 把某个时点的稳定版本冻结为基线 | 需求基线、发布基线 |
基线(baseline):一组经过评审、冻结的配置项,作为后续工作的统一参照点。比如"SRS 基线"冻结后,再改需求就要走正式变更流程。基线让"状态有据可查"——谁改的、何时改的、为什么改,全程留痕。
为什么要变更控制:没有审批的随意修改,会引入新 bug、破坏他人工作、造成版本混乱。变更控制不是"卡流程",而是让每次变更可评估、可追溯。
💡 记忆口诀:配置管理 = 留版本 + 控变更 + 定基线 + 做审计。基线 = 冻结的"标准参考点"。
⚠️ 常见错误
- 把配置管理等同于"用 Git":Git 只是版本控制工具,配置管理还包括变更控制、基线、审计。
- 变更不审批、不记录:基线之后随意改需求/代码,是配置管理最典型的失败。
- 混淆"版本"与"基线":版本是文件的每个历史快照;基线是一组配置项被冻结的稳定状态。
6.5 软件度量:用量化数据说话
无法度量,就无法改进
软件度量(software metrics)是用量化指标衡量软件过程、产品和资源的属性,给质量管理和改进提供数据依据。度量分三类:
| 分类 | 度量对象 | 典型指标 |
|---|---|---|
| 过程度量 | 开发过程怎么样 | 缺陷率、生产率(代码行/人·日)、返工率 |
| 产品度量 | 交付物(代码/文档)本身 | 代码行数、圈复杂度、模块耦合度、文档页数 |
| 资源度量 | 投入的人与工具 | 人员规模、机器数量、工作量(人·月) |
两个经典的产品度量指标:
- 代码行数(LOC):最朴素,容易统计,但不能反映质量——同样功能,100 行精巧代码可能好过 1000 行冗长代码。真实项目中 LOC 常被滥用为绩效指标,这是出了名的"度量陷阱"。
- 圈复杂度(cyclomatic complexity):衡量代码控制流的复杂程度,公式
V(G) = 判定节点数 + 1(一个 if 算一个判定节点)。圈复杂度越高,测试路径越多、越难维护,通常建议控制在 10 以内。
度量在使用时的原则:指标要服务于决策(改进质量、控制进度),不能为了数字而数字;单一指标易被"刷",要结合多个维度看;任何度量都应可操作、可对比、可解释。
💡 记忆口诀:度量三类 = 过程、产品、资源;圈复杂度 = 判定数 + 1,越高越难测难维护。
更多常用度量指标
除代码行数和圈复杂度外,工程上还常用这些指标:
| 指标 | 含义 | 用途 |
|---|---|---|
| 缺陷密度 | 每千行代码(KLOC)的平均缺陷数 | 对比模块/版本质量,越密越需重构 |
| 缺陷去除率 | 交付前被发现的缺陷占总缺陷的比例 | 评价测试充分程度 |
| 平均修复时间 | 缺陷从发现到关闭的平均耗时 | 衡量团队响应与修复能力 |
| 需求变更率 | 需求变更请求占总需求的比例 | 反映需求明确度,过高说明前期需求工作不到位 |
度量的正确姿势:指标要持续收集、横向可比,并最终服务于"改进过程"——比如缺陷密度高的模块,就去重构它、补测试。脱离改进的度量只是数字游戏。
⚠️ 常见错误
- 拿代码行数衡量程序员产出:LOC 与质量、效率不成正比,是典型的错误度量用法。
- 背不出圈复杂度公式:
V(G) = 判定节点个数 + 1,if/while/case 都是判定节点。 - 度量脱离目的:收集一堆数据却不用于改进,度量就成形式主义。
📌 双语术语表(本讲)
| 中文 | English | 记忆点 |
|---|---|---|
| 软件质量 | software quality | 满足需求与期望 |
| 质量模型 | quality model | 把"好"拆成指标 |
| McCall 质量模型 | McCall's model | 运行/修正/转移 |
| ISO/IEC 9126 | ISO 9126 | 六大特性 |
| ISO/IEC 25010 | ISO 25010 | 更现代的质量模型 |
| 改正性维护 | corrective maintenance | 修 bug |
| 适应性维护 | adaptive maintenance | 适配环境 |
| 完善性维护 | perfective maintenance | 加功能 |
| 预防性维护 | preventive maintenance | 防患重构 |
| 配置管理 | configuration management | 版本/变更/基线 |
| 配置项 | configuration item | 受控对象 |
| 基线 | baseline | 冻结的稳定版本 |
| 变更控制 | change control | 审批留痕 |
| 软件度量 | software metrics | 量化指标 |
| 圈复杂度 | cyclomatic complexity | 判定数 + 1 |
⭐ 本讲考点清单
- 质量 = 功能正确 + 质量属性 + 用户满意;缺陷发现越晚修复越贵。
- ISO 9126 六大特性:功能性、可靠性、易用性、效率、可维护性、可移植性;会判断某个子特性属于哪个顶层特性。
- 维护四类型:改正(修 bug)、适应(适配环境)、完善(加功能)、预防(重构);完善性占比最高。
- 维护成本常超开发成本。
- 配置管理四活动:版本控制、变更控制、配置审计、基线管理;基线 = 冻结的稳定参照点。
- 度量三分类:过程、产品、资源;圈复杂度 V(G)=判定节点数+1;代码行数不能衡量质量。