← 返回博客列表

一、引言:软件工程概述

软件工程(Software Engineering)是一门将工程化的方法应用于软件的开发、运行和维护的学科,它涵盖了系统化的、规范的、可量化的方法。在系统架构设计师考试中,软件工程是贯穿始终的核心知识体系,从需求到维护的每一个环节都涉及工程化的思想与方法。

IEEE 经典定义(软考标准表述)
软件工程是:
1. 将系统化的、规范的、可度量的方法应用于软件的开发、运行和维护的过程,即将工程化应用于软件中;
2. 对上述方法的研究。
——出处:IEEE 610.12-1990 软件工程术语标准

1.1 软件危机的由来

20 世纪 60 年代,随着计算机应用的普及,软件规模急剧膨胀,开发效率、质量与维护问题集中爆发,史称"软件危机"(Software Crisis)。1968 年,北约在德国加米施召开的学术会议上首次提出"软件工程"一词,标志着软件工程作为一门独立学科正式诞生。

软件危机的典型表现
· 开发成本与进度严重超支
· 软件质量低、缺陷多、不可维护
· 需求频繁变更,开发无法适应
· 缺乏科学的开发方法和管理规范
· 文档不全、人员流失导致知识断层
· 软件难以追踪和验证("看不到摸不着")

软件危机的根源在于软件本身的特殊性:软件是逻辑产品而非物理产品,看不见摸不着;其复杂性随规模呈非线性增长;且软件不会"磨损",但会因环境变化和需求变更而"退化"。软件工程正是为应对这些挑战而生。

1.2 软件工程三要素

软件工程由三个核心要素构成,三者相辅相成:

软件工程三要素

  • 方法(Methods):提供了"如何做"的技术,包括需求分析、设计、编码、测试、维护等各种方法学,如结构化方法、面向对象方法。
  • 工具(Tools):为方法的运用提供自动化或半自动化支持,如 IDE、版本控制工具、测试工具、CASE 工具。
  • 过程(Process):将方法和工具综合起来以达到合理、及时进行软件开发的目的,定义了活动的顺序、里程碑和交付物。

1.3 软件工程知识体系(SWEBOK)

IEEE 计算机学会发布的 SWEBOK(Software Engineering Body of Knowledge)将软件工程知识划分为 15 个知识域,这是软考复习的总体框架:

知识域 核心内容
软件需求需求工程过程、需求获取、分析、规约、验证与管理
软件设计软件结构设计、详细设计、设计模式、设计原则
软件构造编码、单元测试、调试、代码复用
软件测试测试用例设计、测试策略、缺陷管理
软件维护纠正性、适应性、完善性、预防性维护
软件配置管理版本控制、变更控制、配置审计
软件工程管理项目计划、估算、风险管理、质量管理
软件工程过程过程定义、过程评估、过程改进(CMMI)
软件工程模型与方法建模语言(UML)、结构化方法、面向对象方法
软件质量质量属性、质量模型、质量保证、评审与审计
考试视角
软考系统架构设计师考试中,软件工程知识是上午综合知识题和下午案例分析题的重点考查内容。其中软件开发模型、需求工程、软件设计、软件测试是高频考点,必须重点掌握。

二、软件生命周期

软件生命周期(Software Life Cycle)是指软件产品从构思、定义、开发、使用、维护到退役的整个过程,又称软件生存周期。将生命周期划分为若干阶段,便于管理和控制每个阶段的质量、成本和进度。

2.1 生命周期阶段划分

国标 GB/T 8566 将软件生命周期划分为若干阶段,软考通常采用以下经典划分:

1. 可行性研究与计划(Feasibility Study) 2. 需求分析(Requirements Analysis) 3. 概要设计 / 详细设计(Design) 4. 编码(Coding / Implementation) 5. 测试(Testing) 6. 运行 / 维护(Maintenance) 里程碑 可行性报告 需求规格说明书 设计说明书 源代码 测试报告 可运行系统 图示:经典瀑布式生命周期,每阶段产出明确里程碑交付物
图 1:软件生命周期瀑布模型阶段与里程碑

2.2 各阶段任务与交付物

阶段 核心任务 关键交付物 里程碑
可行性研究 确定项目是否值得做、能否做,从技术、经济、操作、法律等角度论证 可行性研究报告、项目计划 立项决策
需求分析 明确系统"做什么",确定功能需求、非功能需求与约束 软件需求规格说明书(SRS) 需求评审通过
概要设计 将需求转化为软件体系结构,划分模块、定义接口 概要设计说明书(HLD) 架构评审通过
详细设计 为每个模块设计内部算法、数据结构、接口细节 详细设计说明书(LLD) 设计评审通过
编码 将详细设计翻译为程序代码,遵循编码规范 源程序、单元测试脚本 代码完成
测试 发现并修复缺陷,验证是否满足需求 测试计划、测试用例、测试报告 验收通过
维护 运行期间的纠错、适配、完善与预防 维护记录、变更文档 退役
软考易混点:三种可行性
1. 技术可行性:现有技术能否实现?风险多大?
2. 经济可行性:成本-收益分析(ROI),是否值得投资?
3. 操作/运行可行性:用户能否接受、能否顺利运行?
此外还有法律可行性(是否侵权、合规)与方案可行性(多种备选方案对比)。

2.3 软件维护的四种类型

软件维护是生命周期中持续时间最长、成本最高的阶段。维护活动分为四类,是软考的高频考点:

维护类型 触发原因 占比 举例
改正性维护 发现并修复遗留缺陷 约 20% 修复支付金额计算错误的 Bug
适应性维护 适应环境变化(硬件、OS、法规) 约 25% 系统从 Windows 迁移到 Linux
完善性维护 用户提出新需求、改善性能 约 50%(占比最大) 增加报表导出 Excel 功能
预防性维护 主动改进可维护性、可靠性 约 5% 重构代码、更新文档
记忆口诀:改正(改错)→ 适应(环境)→ 完善(新功能)→ 预防(未雨绸缪)。完善性维护占比最大,这是软考常考的判断题。

三、软件开发模型(高频考点!)

软件开发模型(Software Development Model)是软件工程过程的具体实例化,它规定了软件开发活动中各阶段的执行顺序、衔接关系以及交付要求。不同模型反映了不同的过程哲学。本章是软考系统架构设计师考试的绝对高频考点,必须熟练掌握每个模型的特征、优缺点和适用场景。

备考策略
对每种模型,请按以下五要素记忆:
1. 核心思想:模型基于什么理念?
2. 过程特征:阶段如何组织?是否迭代、是否增量?
3. 优缺点:至少各记 3 条;
4. 适用场景:什么样的项目最适合?
5. 典型图表:能画出示意图。

3.1 瀑布模型(Waterfall Model)

瀑布模型由 Winston Royce 于 1970 年提出,是最早的、也是最经典的软件开发模型。它将生命周期划分为顺序的、依赖的阶段,前一个阶段的输出作为后一个阶段的输入,像瀑布一样逐级下落,不可回溯(严格意义上的瀑布模型)。

需求分析 设计 编码 测试 维护 反馈/回溯 严格按顺序执行,前阶段完成才进入后阶段 带反馈箭头的是 Royce 改进版"带反馈的瀑布模型" 真实项目中往往允许有限的回溯
图 2:瀑布模型 —— 阶段顺序下落,理想情况下不可回溯

瀑布模型核心特征

  • 阶段顺序性:前一阶段完成后才进入下一阶段,阶段间有明确的里程碑和评审
  • 文档驱动:每阶段必须产出规范的文档,文档是阶段衔接的纽带
  • 严格评审:每阶段结束前进行评审,评审通过才能进入下一阶段
  • 推迟实现:编码在需求、设计完成后才开始,避免过早编码
  • 可见性差:用户直到测试阶段才能看到可运行系统
优点
  • 过程清晰、阶段分明,易于管理和控制
  • 文档完整,有利于团队协作和后续维护
  • 每个阶段都有明确的里程碑和质量基线
  • 适合需求稳定、技术成熟的项目
缺点
  • 无法应对需求变更,灵活性差
  • 用户直到很晚才能看到可运行产品
  • 前期缺陷发现晚,修复成本高
  • 文档工作量大,效率低
适用场景
· 需求非常明确且稳定;
· 技术成熟、风险低;
· 大型、复杂的系统软件(如航天、军工、金融核心);
· 合同型项目,需求由甲方严格定义。

3.2 增量模型(Incremental Model)

增量模型将软件拆分为若干个增量构件,每个增量实现一部分功能。第一个增量通常是核心功能("最小可用产品"),后续增量逐步添加新功能。每个增量本身经历需求、设计、编码、测试的完整小型瀑布。

时间 需求 设计 编码 测试 发布增量 1 增量 1(核心) 需求 设计 编码 测试 发布增量 2 增量 2 需求 设计 编码 测试 发布增量 3 增量 3(完整) 每个增量是一个小型瀑布,逐步交付可用功能
图 3:增量模型 —— 分批次交付,每批都是一个完整的小瀑布
优点
  • 用户较早得到核心功能,信心强
  • 优先级高的功能先开发、先测试,风险早暴露
  • 每个增量可独立部署、独立验收
  • 资金分批投入,便于控制投入产出
缺点
  • 增量划分困难,接口需提前规划
  • 后续增量可能影响已交付功能,需回归测试
  • 要求软件架构必须开放、可扩展
  • 总成本可能高于瀑布模型
适用场景
· 核心功能明确但完整功能可分期交付;
· 需要快速投入市场获取反馈;
· 资金分批到位的项目;
· 团队能力较强,能预先规划好可扩展的架构。

3.3 螺旋模型(Spiral Model)

螺旋模型由 Barry Boehm 于 1988 年提出,是一种风险驱动的迭代模型。它将瀑布模型与原型模型结合,并引入风险分析环节。每轮螺旋分为四个象限:制定计划 → 风险分析 → 实施工程 → 客户评估,每完成一轮螺旋就向中心收拢,软件逐步完善。

① 制定计划 目标/方案/约束 ② 风险分析 识别/评估/规避 ③ 实施工程 开发/验证 ④ 客户评估 评审/下一轮 交付 第1轮 第2轮 第3轮 每轮螺旋都经过 4 个象限,逐步收敛
图 4:螺旋模型 —— 风险驱动的迭代过程,每轮四象限
螺旋模型的关键特征
· 最大特点:风险分析,是唯一显式包含风险评估的模型;
· 每一轮都包含完整的目标设定→风险评估→开发→评审循环;
· 适用于大规模、复杂、高风险的项目;
· 依赖有经验的风险分析专家,否则风险分析流于形式。
优点
  • 显式风险分析,支持高风险项目
  • 迭代开发,灵活适应需求变化
  • 客户参与每轮评估,反馈及时
  • 结合了瀑布的严谨与原型的灵活
缺点
  • 风险分析成本高,依赖专家
  • 过程复杂,管理难度大
  • 对小项目、低风险项目过于"重型"
  • 难以确定何时结束螺旋

3.4 喷泉模型(Fountain Model)

喷泉模型是面向对象开发中常用的模型,它强调迭代和无间隙。各阶段(分析、设计、编码)没有严格的界限,可以交叉、重叠,像喷泉水花一样相互喷涌、回溅。

面向对象开发 分析 设计 实现 阶段重叠、迭代进行,强调无间隙
图 5:喷泉模型 —— 面向对象开发的迭代无间隙模型
喷泉模型核心特征
· 迭代性:分析、设计、实现可反复进行;
· 无间隙性:阶段无明显边界,可交叉重叠;
· 面向对象:与 OOA/OOD/OOP 自然契合;
· 自下而上代表分析与设计逐步深化。
优点
  • 与面向对象方法无缝衔接
  • 支持迭代,灵活应对变化
  • 阶段交叉提高了开发效率
缺点
  • 阶段界限模糊,管理与控制难
  • 对文档和评审要求高,否则易混乱
  • 不适用于面向过程开发

3.5 V 模型(V-Model)

V 模型是瀑布模型的变种,它将开发活动与测试活动一一对应。左半边自上而下是定义阶段(需求分析→概要设计→详细设计→编码),右半边自下而上是测试阶段(单元测试→集成测试→系统测试→验收测试),整体呈"V"字形。

需求分析 概要设计 详细设计 编码 单元测试 集成测试 系统测试 验收测试 需求 ↔ 验收测试 概要设计 ↔ 系统测试 详细设计 ↔ 集成测试 开发阶段与测试阶段一一对应,左定义右验证 核心思想:测试用例在需求/设计阶段就开始准备
图 6:V 模型 —— 开发与测试的对应关系
V 模型对应关系(必背)
· 需求分析 ↔ 验收测试:验收测试用例基于需求编写
· 概要设计 ↔ 系统测试:系统测试验证整体设计
· 详细设计 ↔ 集成测试:集成测试验证模块间接口
· 编码 ↔ 单元测试:单元测试验证代码逻辑
优点
  • 测试与开发同步规划,质量有保障
  • 缺陷可在对应的早期阶段被发现
  • 阶段对应关系清晰,便于管理
缺点
  • 仍属线性模型,对需求变更应对不足
  • 测试准备需要早期投入资源
  • 实际可执行系统仍要到后期才出现

3.6 快速原型模型(Rapid Prototyping)

快速原型模型在需求分析阶段快速构建一个可运行的原型系统,让用户直观体验并提出修改意见,反复迭代直到用户满意。原型可以抛弃(抛弃式原型)或演化成最终产品(演化式原型)。

倾听用户 构建/修改原型 用户测试原型 需求确认 原型迭代循环 快速构建→用户反馈→修改→确认,循环直至需求明确
图 7:快速原型模型 —— 围绕原型进行迭代
优点
  • 用户早期参与,需求获取准确
  • 原型直观,减少需求误解
  • 开发周期短,响应快
  • 适合需求不明确的项目
缺点
  • 原型可能成为最终产品,质量难保障
  • 缺乏系统设计,可维护性差
  • 用户可能误以为原型就是产品
  • 需要快速开发工具支持

3.7 迭代模型 / 敏捷开发(Agile)

敏捷开发是一种以人为核心、迭代、循序渐进的开发方法。2001 年发布的敏捷宣言确立了四大价值观:个体与互动高于流程工具;可工作软件高于详尽文档;客户合作高于合同谈判;响应变化高于遵循计划。

敏捷宣言的 12 条原则(节选)
· 尽早、持续地交付有价值的软件;
· 欣迎需求变化,即使在开发后期;
· 业务人员与开发人员每日协作;
· 围绕有动机的人构建项目,给予信任;
· 面对面交流是最有效的沟通方式;
· 可工作软件是进度的首要度量。

Scrum 是敏捷开发中最流行的过程框架。它将项目划分为若干固定时长的Sprint(冲刺,通常 2~4 周),每个 Sprint 交付一个可工作的增量。

产品待办 Product Backlog Sprint 计划 Sprint Planning Sprint 待办 Sprint Backlog Sprint 2~4 周 每日站会 15 分钟 潜在 可发布 增量 Sprint 评审 Review Sprint 回顾 Retrospective 回顾反馈 → 下一轮 Sprint 计划 三个核心角色 产品负责人 (PO) 管理产品待办 Scrum Master 促进流程、消除障碍 开发团队 自组织跨职能 Scrum:固定时长 Sprint、每日站会、评审与回顾形成闭环
图 8:Scrum 敏捷过程框架
优点
  • 快速响应变化,适应需求不确定
  • 持续交付可用软件,客户满意度高
  • 团队沟通紧密,氛围好
  • 风险早暴露早解决
缺点
  • 文档较少,不利于后期维护
  • 依赖高素质团队,新人难融入
  • 大规模项目协调困难
  • 进度和成本难以预测

3.8 统一过程(RUP / UP)

统一过程(Rational Unified Process,RUP)是由 Rational 公司(IBM)提出的一种用例驱动、以架构为中心、迭代和增量的软件开发过程框架。RUP 是一个可裁剪的过程框架,包含四个阶段和九个核心工作流。

RUP 三大特征(必背)
1. 用例驱动:用例是需求获取、设计、测试、沟通的核心线索;
2. 以架构为中心:架构是项目骨架,为不同视角提供共同理解;
3. 迭代和增量:项目分解为多次迭代,每次迭代产生增量。
初始阶段 Inception 细化阶段 Elaboration 构造阶段 Construction 移交阶段 Transition LCO 生命周期目标 LCA 生命周期架构 IOC 初始运行能力 PR 产品发布 业务建模 需求 分析与设计 实现 测试 部署 支持工作流:配置与变更管理、项目管理、环境 4 个阶段 + 9 个工作流,横条表示该工作流在阶段中的工作量
图 9:RUP 四阶段九工作流

RUP 四个阶段

  • 初始(Inception):确定项目范围与愿景,识别关键用例,估算成本与风险。里程碑:LCO 生命周期目标。
  • 细化(Elaboration):分析问题域,建立稳健的架构基线,制定项目计划,淘汰高风险。里程碑:LCA 生命周期架构。
  • 构造(Construction):开发所有组件和特性,集成形成产品。里程碑:IOC 初始运行能力。
  • 移交(Transition):将产品移交用户,包括培训、安装、Beta 测试。里程碑:PR 产品发布。

RUP 九个核心工作流

  • 工程类(6 个):业务建模、需求、分析与设计、实现、测试、部署
  • 支持类(3 个):配置与变更管理、项目管理、环境

3.9 DevOps

DevOps 是 Development(开发)和 Operations(运维)的组合,强调开发、测试、运维的紧密协作,通过自动化实现持续集成(CI)、持续交付/部署(CD),从而缩短交付周期、提高发布质量。

Dev 开发 编码/构建 Ops 运维 部署/监控 计划 Plan 编码 Code 构建 Build 测试 Test 发布 Release 部署 Deploy 运维 Operate 监控 Monitor CI 持续集成 CD 持续交付 DevOps 无限循环:开发与运维紧密协作,自动化闭环
图 10:DevOps 无限循环
DevOps 关键实践
· 持续集成(CI):开发人员频繁提交代码到主干,自动构建与测试;
· 持续交付(CD):自动将代码部署到类生产环境,可随时发布;
· 持续部署:自动将通过测试的代码部署到生产环境;
· 基础设施即代码(IaC):用代码管理基础设施;
· 监控与日志:实时监控运行状态,快速定位问题;
· 微服务与容器化:Docker + Kubernetes 是 DevOps 的基础设施。

3.10 开发模型对比总结

模型 核心特征 驱动方式 适用场景
瀑布模型 线性顺序,文档驱动 文档 需求明确稳定
增量模型 分批交付,逐步增加功能 需求优先级 核心功能可早交付
螺旋模型 迭代 + 风险分析 风险 大规模高风险项目
喷泉模型 迭代无间隙 对象 面向对象开发
V 模型 开发与测试一一对应 测试 对测试严格要求的系统
快速原型 原型驱动,快速反馈 原型 需求不明确
敏捷开发 短迭代,拥抱变化 价值 需求多变、中小项目
RUP 用例驱动、架构为中心、迭代 用例+架构 大型复杂项目
DevOps 开发运维一体,自动化 自动化 互联网持续交付
软考选型口诀
· 需求明确、稳定 → 瀑布
· 风险高、规模大 → 螺旋
· 需求不明确 → 原型
· 核心功能优先 → 增量
· 面向对象 → 喷泉
· 测试严格 → V 模型
· 需求多变、小型 → 敏捷
· 大型统一过程 → RUP
· 持续交付、互联网 → DevOps

四、需求工程

需求工程(Requirements Engineering)是软件工程中最关键的阶段之一。研究表明,软件项目中约 40%~50% 的缺陷源于需求问题。需求工程不仅是"写下需求",而是一个包含获取、分析、规约、验证与管理的完整过程。

4.1 需求工程过程

需求工程五步骤

  • 需求获取:通过访谈、问卷、观察、JAD 会议等方式从干系人收集需求
  • 需求分析:对原始需求进行综合、提炼、建模,消除冲突与歧义
  • 需求规约:将分析结果编写为软件需求规格说明书(SRS)
  • 需求验证:通过评审、原型、形式化方法验证需求的正确性、完整性、一致性
  • 需求管理:基线化、变更控制、版本管理、需求跟踪

4.2 需求的类型

类型 定义 举例
功能需求 系统"必须做什么"——输入、处理、输出 用户可以查询订单状态
非功能需求 系统"做得怎么样"——性能、可靠性、易用性、安全性 响应时间 < 200ms;可用性 99.9%
设计约束 限制设计选择的条件(技术、标准、法规) 必须使用 Oracle 数据库;遵守 GDPR
接口需求 与外部系统的交互(用户接口、硬件、软件、通信) 提供 RESTful API 给第三方
易混点提醒
· "系统必须支持 1000 并发用户"——是非功能需求(性能);
· "系统必须用 Java 编写"——是设计约束,不是功能需求;
· "用户可以通过手机号登录"——是功能需求;
· "密码必须加密存储"——既是功能需求也是非功能需求(安全),需视语境判断。

4.3 需求分析方法

需求分析主要有两种方法:结构化分析(SA)和面向对象分析(OOA)。

维度 结构化分析(SA) 面向对象分析(OOA)
核心思想功能分解,自顶向下对象抽象,识别类与对象
建模工具DFD、数据字典、实体关系图、状态转换图用例图、类图、顺序图、状态图(UML)
关注点数据流与功能对象、属性、方法、关系
适用数据处理类系统复杂业务系统、面向对象开发

4.4 结构化分析与数据流图(DFD)

数据流图(Data Flow Diagram, DFD)是结构化分析的核心工具,用于描述系统内数据的流动与变换。DFD 有四种基本符号:

DFD 四种基本符号
1. 外部实体(External Entity):系统外的人员、组织或系统,用矩形表示;
2. 加工(Process):对数据的处理,用圆形或圆角矩形表示;
3. 数据存储(Data Store):数据的保存处,用双横线或开口矩形表示;
4. 数据流(Data Flow):数据的流动,用带箭头的线表示。

DFD 是分层的,从顶层向下逐步细化:

  1. 顶层图(上下文图):把整个系统看作一个加工,只显示外部实体与系统间的数据流。
  2. 0 层图(Level 0):将顶层加工分解为若干主要加工。
  3. 1 层图(Level 1):继续细化每个 0 层加工。
  4. 更低层:直到每个加工足够清晰、可独立实现为止。
顶层图(Context Diagram) 读者 0 图书系统 管理员 借书请求 借阅结果 图书信息 入库 0 层图(Level 0) 读者 1 借阅 2 归还 3 查询 4 入库 管理员 D1 图书库 D2 读者库 图例: 外部实体 加工 数据存储 数据流 左:将系统视为一个加工的顶层图;右:分解为 4 个加工的 0 层图 继续细化可得到 1 层、2 层图,直到每个加工清晰可独立实现 配套工具:数据字典(DD) 对 DFD 中的数据流、数据存储进行精确定义,包括数据项、数据结构、数据流、数据存储四类条目
图 11:图书管理系统 DFD 示例(顶层图与 0 层图)

4.5 需求跟踪矩阵

需求跟踪矩阵(Requirements Traceability Matrix, RTM)是需求管理的核心工具,用于建立需求-设计-代码-测试之间的双向追溯关系。它确保每个需求都有对应的设计、实现和测试用例,避免需求遗漏。

需求 ID 需求描述 设计模块 代码文件 测试用例 状态
REQ-001 用户登录 AuthService auth.py TC-101/102 已完成
REQ-002 订单查询 OrderService order.py TC-201/202 测试中
REQ-003 报表导出 ReportService report.py TC-301 设计中

五、软件设计

软件设计是将需求转化为软件结构的过程。它分为概要设计(高层架构与模块划分)和详细设计(模块内部算法与数据结构)。好的设计是高质量软件的基础。

5.1 软件设计过程

概要设计与详细设计

  • 概要设计(HLD):将系统分解为模块,定义模块间接口与调用关系,确定数据结构、数据库模式、运行设计、出错处理。产出:概要设计说明书。
  • 详细设计(LLD):为每个模块设计内部算法、数据结构、流程图、输入输出。产出:详细设计说明书,应能达到"程序员可直接编码"的精度。

5.2 结构化设计:模块化与内聚耦合

结构化设计的核心是模块化——将系统分解为若干相对独立的模块。衡量模块独立性的两个定性指标是内聚(Cohesion)和耦合(Coupling)。设计原则是:高内聚、低耦合。

核心原则:高内聚、低耦合
· 高内聚:模块内部各元素彼此紧密结合,共同完成一个明确的任务;
· 低耦合:模块之间联系尽可能少,接口简单;
· 高内聚使模块功能明确、易理解、易复用;低耦合使模块独立性强,修改影响小。

5.2.1 内聚的七种类型(由低到高)

级别 类型 含义 举例
最低偶然内聚模块内各元素无实质联系,只是为节省代码而放在一起一个工具函数同时打印日志、计算日期、读文件
低逻辑内聚模块内完成逻辑上相关的多种功能,由参数决定执行哪个print(type, data) 根据类型打印不同报表
中时间内聚模块内各功能在同一时间段执行系统初始化函数同时打开文件、连接数据库、加载配置
中过程内聚模块内各功能按特定顺序执行,前后依赖按顺序读取输入→校验→计算→输出的处理流程
中高通信内聚模块内各功能操作同一数据集,但顺序无依赖同时计算学生总分和平均分(同一成绩数据)
高顺序内聚前一功能的输出是后一功能的输入读取数据→解析数据→保存数据
最高功能内聚模块所有元素共同完成一个单一、明确的功能计算圆面积的函数

5.2.2 耦合的七种类型(由高到低)

级别 类型 含义 举例
最高内容耦合一个模块直接访问另一模块的内部数据或代码GOTO 跳入另一模块;修改另一模块的变量
高公共耦合多个模块共享同一个全局数据结构多个模块读写同一全局变量
高外部耦合多个模块访问同一外部数据(如同一文件)多个模块都读写 config.txt
中控制耦合模块间传递控制信息(如标志位)影响对方逻辑传递 mode="admin" 决定走哪个分支
中低标记耦合模块间传递数据结构(记录)传递整个用户对象,但只用了几个字段
低数据耦合模块间只传递简单数据参数传递 userId 字符串查询用户
最低非直接耦合模块之间无直接联系,通过主模块控制两个独立模块由主程序分别调用
内聚与耦合的强弱频谱 内聚(高 → 低 优): 偶然 逻辑 时间 过程 通信 顺序 功能★ 低内聚 高内聚 耦合(低 → 高 优): 内容 公共 外部 控制 标记 数据 非直接★ 高耦合(差) 低耦合(优) ✓ 推荐区域 功能内聚 + 数据/非直接耦合 模块独立性强,易维护 ✗ 应避免 偶然/逻辑内聚 + 内容/公共耦合 模块杂乱,难维护 设计目标:高内聚(功能内聚)+ 低耦合(数据耦合或非直接耦合) ★ 表示最理想状态
图 12:内聚与耦合的强弱频谱对比
记忆技巧
内聚由低到高口诀:"偶逻时过通顺功"(偶然-逻辑-时间-过程-通信-顺序-功能)
耦合由高到低口诀:"内公外控标数非"(内容-公共-外部-控制-标记-数据-非直接)
功能内聚最好,偶然内聚最差;非直接耦合最好,内容耦合最差。

5.3 面向对象设计原则(SOLID)

面向对象设计遵循五大原则,合称 SOLID:

缩写 原则 核心思想
S 单一职责原则(SRP) 一个类应该只有一个引起它变化的原因
O 开闭原则(OCP) 对扩展开放,对修改关闭
L 里氏替换原则(LSP) 子类必须能替换父类且不影响程序正确性
I 接口隔离原则(ISP) 客户端不应依赖它不需要的接口
D 依赖倒置原则(DIP) 依赖抽象,不依赖具体;高层不依赖低层

5.4 软件设计度量

软件设计质量可通过一系列度量指标衡量:

六、软件测试

软件测试是软件质量保证的重要手段,目标是发现缺陷并评估质量。测试不能证明软件无错,但能暴露已知问题。IEEE 将测试定义为"通过运行程序来观察、分析其行为以验证质量属性的过程"。

6.1 测试级别

软件测试分为四个层次,由低到高、由小到大:

单元测试 Unit 集成测试 Integration 系统测试 System 验收测试(Acceptance) 由开发执行 测试函数/方法 占比:70% 由测试执行 模块间接口 占比:20% 由测试执行 整体功能/性能 占比:10% 用户参与 测试金字塔:越底层占比越大、成本越低
图 13:软件测试金字塔
级别 测试对象 执行者 关注点
单元测试函数/方法/类开发人员内部逻辑、边界值、错误处理
集成测试模块间接口测试人员接口、数据流、调用关系
系统测试整个系统测试人员功能、性能、安全、兼容性
验收测试用户视角用户/客户是否满足业务需求,是否可发布

集成测试的策略

6.2 测试方法

6.2.1 黑盒测试

黑盒测试将软件视为"黑盒",不考虑内部结构,仅根据需求规格说明设计测试用例。常用方法:

方法 核心思想 适用场景
等价类划分 将输入域划分为有效/无效等价类,每类选代表值 输入数据范围明确
边界值分析 测试边界及其附近的值(缺陷常出现在边界) 数值范围、数组、日期
判定表 列出条件组合与对应动作的表格 多条件组合的复杂逻辑
因果图 用图表示输入条件(因)与输出(果)的关系 条件间存在约束关系
错误推测 凭经验列出可能出错的场景 补充测试用例

6.2.2 白盒测试

白盒测试基于程序内部结构和逻辑设计测试用例。常用的覆盖标准由弱到强为:

覆盖标准 含义 强度
语句覆盖每条语句至少执行一次最弱
判定覆盖(分支覆盖)每个判定的真假分支至少执行一次弱
条件覆盖每个条件的真假至少取一次中
判定/条件覆盖同时满足判定覆盖和条件覆盖中
条件组合覆盖每个判定中所有条件组合至少出现一次强
路径覆盖程序中所有可能路径至少执行一次最强
覆盖强度关系(必背)
· 语句覆盖 < 判定覆盖 < 条件覆盖 < 判定/条件覆盖 < 条件组合覆盖 < 路径覆盖
· 路径覆盖 > 条件组合覆盖 > 判定/条件覆盖 > 判定覆盖 ≈ 条件覆盖 > 语句覆盖
· 语句覆盖是最弱的,路径覆盖是最强的。
· 注意:条件覆盖不一定强于判定覆盖(二者侧重点不同),但条件组合覆盖一定强于二者。

6.3 McCabe 圈复杂度

McCabe 圈复杂度(Cyclomatic Complexity)用于衡量程序的逻辑复杂度,由 Thomas McCabe 提出。它基于控制流图计算,公式为:

圈复杂度公式
V(G) = E - N + 2P
其中:
· E:控制流图的边数
· N:控制流图的节点数
· P:连通分量数(通常为 1,简化为 V(G) = E - N + 2)

另一种简化公式:V(G) = 判定节点数 + 1(适用于单入口单出口的程序)
圈复杂度判别标准
· V(G) ≤ 10:简单,易测试
· 10 < V(G) ≤ 20:中等复杂
· 20 < V(G) ≤ 50:复杂,需重构
· V(G) > 50:极复杂,错误率高,必须重构
圈复杂度也代表了独立路径数,即至少需要的测试用例数。

6.4 测试驱动开发(TDD)

测试驱动开发(Test-Driven Development)是敏捷开发中的一种实践,由 Kent Beck 提出。其核心是"先写测试,再写代码",循环过程为:红-绿-重构。

TDD 三步骤循环

  • 红(Red):编写一个会失败的测试用例,描述待实现的功能
  • 绿(Green):编写最简单的代码使测试通过
  • 重构(Refactor):在测试保护下改进代码结构,消除重复

6.5 案例:电商结算模块测试

案例背景

某电商平台结算模块负责计算订单最终支付金额。规则如下:

  • 商品金额满 100 元打 9 折;满 500 元打 8 折
  • 使用优惠券抵扣 20 元(订单金额需 ≥ 50 元才可用券)
  • 运费:订单金额 ≥ 99 元免邮;否则 +10 元运费
  • 会员等级折扣与商品折扣不叠加

测试设计(黑盒-等价类划分 + 边界值)

输入条件 有效等价类 无效等价类 边界值
商品金额 0 < x < 100;100 ≤ x < 500;x ≥ 500 x ≤ 0;非数字 0, 1, 99, 100, 499, 500
是否用券 用券且 x ≥ 50;不用券 用券但 x < 50 49, 50, 51
是否会员 是会员;非会员 — —

关键测试用例

用例 输入 预期输出 覆盖
TC-1金额=99,无券,非会员99 + 10 = 109边界值
TC-2金额=100,无券,非会员90 + 0 = 90折扣边界
TC-3金额=500,用券,非会员400 - 20 + 0 = 380折扣边界+券
TC-4金额=49,用券提示:金额不足,不可用券无效等价类
TC-5金额=50,用券,非会员50 - 20 + 10 = 40券边界
TC-6金额=200,无券,会员(8 折)160 + 0 = 160会员折扣
设计要点
· 边界值是缺陷高发区,0、99、100、500 必须覆盖;
· 等价类划分要包含无效等价类,验证系统的容错;
· 多条件组合使用判定表设计,避免遗漏组合;
· 白盒测试关注 if-else 分支覆盖,确保每个分支都被执行。

七、软件配置管理

软件配置管理(Software Configuration Management, SCM)是软件工程中用于标识、组织、控制修改的一组活动。其目标是建立和维护软件产品在整个生命周期中的完整性。

7.1 配置管理核心概念

SCM 四大功能
1. 配置标识:识别配置项,命名、版本化;
2. 配置控制:变更的评估、审批、实施与记录;
3. 配置状态报告:记录并报告配置项的状态变化;
4. 配置审计:验证配置项是否符合需求与标准。

配置项(Configuration Item, CI)是配置管理的对象,包括:源代码、文档、数据、可执行程序、开发环境、第三方库版本等。

基线(Baseline)是经过正式评审和批准的配置项快照,作为后续开发的基准。基线一旦建立,变更必须通过正式的变更控制流程。

7.2 版本控制:SVN vs Git

维度 SVN(集中式) Git(分布式)
架构集中式,依赖中央服务器分布式,每个克隆都是完整仓库
离线工作不支持,必须连服务器支持,本地可提交
分支较重,复制目录轻量,指针切换
速度受网络影响本地操作,快
权限控制可按目录细粒度控制仓库级,较粗
典型场景企业内部、文档管理开源、代码托管

7.3 变更控制流程

变更控制是配置管理的核心活动。任何对基线的修改都必须经过正式的变更控制流程,避免随意修改导致混乱。

提出变更请求 CCB 评审 批准? CCB 驳回/修改后重提 批准 实施变更 验证测试 更新基线 CCB(变更控制委员会) · 评估变更对成本、进度、质量的影响 · 批准或驳回变更请求 · 由项目经理、架构师、QA、客户代表组成 · 任何对基线的修改都需 CCB 批准 · 变更实施后需回归测试与配置审计 注:紧急变更可走快速通道,但事后需补评审 配置变更控制流程:提出 → CCB 评审 → 实施 → 验证 → 更新基线
图 14:软件配置管理变更控制流程
配置审计的两种类型
1. 功能配置审计(FCA):验证配置项的实际功能是否符合需求;
2. 物理配置审计(PCA):验证配置项的物理形态(代码、文档)是否与基线一致。

八、软件质量保证

软件质量是软件满足明确或隐含需求的程度。软件质量保证(SQA)是一组系统化的活动,确保软件产品符合规定质量标准。

8.1 软件质量模型

ISO/IEC 9126 质量模型

ISO 9126 将软件质量分为六大特性(外层)和 21 个子特性:

质量特性 含义 子特性
功能性 满足明确和隐含需求的能力 适合性、准确性、互操作性、依从性、安全性
可靠性 在规定条件下维持性能的能力 成熟性、容错性、易恢复性
易用性 用户理解、学习、使用的难易 易理解性、易学性、易操作性
效率 资源使用与性能的关系 时间特性、资源特性
可维护性 修改的难易程度 易分析性、易改变性、稳定性、易测试性
可移植性 转移到新环境的能力 适应性、易安装性、遵循性、易替换性
记忆口诀:功可易效维移(功能-可靠-易用-效率-可维护-可移植)。
软考易混点:功能性包含"安全性"(访问控制);可靠性包含"容错性"(出错后继续运行)和"易恢复性"(出错后恢复)。

McCall 质量模型

McCall 模型从三个视角定义 11 个质量因素:

8.2 质量保证 vs 质量控制

维度 质量保证(QA) 质量控制(QC)
目标预防缺陷,过程导向发现缺陷,产品导向
关注点开发过程是否符合规范产品是否符合质量标准
手段审计、评审、培训、标准制定测试、检查、度量
时机贯穿全生命周期主要在测试阶段
执行者SQA 工程师测试人员

8.3 软件评审与审查

软件评审是质量保证的重要活动,主要包括:

8.4 CMM / CMMI 能力成熟度模型

能力成熟度模型集成(CMMI)是评估组织软件过程成熟度的标准。CMMI 分为五个成熟度等级:

1 初始级 无序、依赖个人 2 已管理级 项目级管理 3 已定义级 组织级标准过程 4 量化管理级 定量度量与控制 5 优化级 持续改进 成熟度提升方向(过程越规范,等级越高) CMMI 五级成熟度阶梯
图 15:CMMI 五级成熟度模型
等级 名称 特征 关键过程域
1初始级(Initial)无序、依赖英雄主义无
2已管理级(Managed)项目级有规范,可重复需求管理、配置管理、项目计划
3已定义级(Defined)组织级标准过程组织过程聚焦、培训、同行评审
4量化管理级(Quantitatively Managed)用数据量化管理组织过程性能、定量项目管理
5优化级(Optimizing)持续改进、技术创新组织创新与部署、原因分析与解决
软考记忆要点
· 等级 1 是"无序",等级 5 是"持续优化";
· 等级 3 是分水岭——从"项目级"到"组织级"的跨越;
· 等级 4 引入定量管理(数据驱动);
· 等级 5 强调持续改进与创新。

九、项目管理基础

软件项目管理是为了在约定的时间、成本、质量约束下完成软件产品而进行的一系列活动。PMBOK 将项目管理划分为 10 大知识领域。

9.1 项目三角形

项目管理有三大核心要素:范围、时间、成本,外加质量构成"项目铁三角"。三者相互制约,改变其一必然影响其他。

项目铁三角
· 范围:项目要做什么
· 时间:完成需要多久
· 成本:投入多少资源
· 质量:达到什么标准
中心是质量。三角任一边变化都会影响其他两边,并最终影响质量。

9.2 项目管理十大知识领域

项目 管理 1.整合 管理 2.范围 管理 3.进度 管理 4.成本 管理 5.质量 管理 6.人力 资源 7.沟通 管理 8.风险 管理 9.采购 管理 10.干系人 管理 PMBOK 项目管理十大知识领域
图 16:PMBOK 十大项目管理知识领域

9.3 进度管理:甘特图与关键路径

甘特图(Gantt Chart)用横条表示任务的开始、结束和进度,直观但不反映任务间依赖关系。

PERT/CPM(关键路径法)用网络图表示任务及其依赖,找出决定项目最短工期的关键路径。关键路径上的任务延误会直接影响项目交付。

关键路径相关公式
· 最早开始时间 ES:所有前置任务完成后最早能开始的时间
· 最早结束时间 EF = ES + 工期
· 最晚结束时间 LF:不影响总工期的最晚完成时间
· 最晚开始时间 LS = LF - 工期
· 总浮动时间 = LS - ES = LF - EF
· 关键路径:总浮动时间为 0 的路径(最长路径)

9.4 风险管理

风险管理包括风险识别、风险评估、风险规划和风险控制四个步骤。

风险类型 举例 应对策略
项目风险人员流失、进度延误规避、转移、减轻、接受
技术风险新技术不成熟、架构错误原型验证、技术评审
商业风险市场需求变化、竞争市场调研、灵活应变

十、实战案例:ERP 系统软件工程实践

下面以一个中型制造企业的 ERP 系统开发为例,完整演示软件工程各阶段如何落地。

项目背景

  • 客户:某机械制造企业,员工 500 人,年营收 2 亿
  • 目标:替换老旧的财务+进销存独立系统,建设一体化 ERP
  • 模块:采购、库存、生产、销售、财务、人力资源
  • 预算:300 万元;工期:12 个月;团队:15 人
  • 约束:核心财务模块必须 6 个月内上线(影响年度审计)

10.1 模型选型

项目特点:规模较大、有明确核心模块优先上线要求、需求部分明确但部分需探索。综合考虑,采用增量模型 + 螺旋模型的混合策略:

选型理由
· 增量模型保证核心财务模块 6 个月上线,满足审计约束;
· 螺旋模型的风险分析应对数据迁移、老系统集成等不确定性;
· Scrum 的短迭代适应业务部门逐渐明确的需求;
· CI/CD 保证多模块并行开发的质量。

10.2 需求分析

需求工程采用用例驱动的面向对象分析方法:

10.3 设计决策

设计决策 选择 理由
架构风格B/S + 分层 + 微服务跨地域办公、独立部署
数据库Oracle(财务)+ MySQL(业务)财务要强一致性;业务要高性能
模块设计高内聚低耦合各模块独立部署、独立扩展
接口设计RESTful API + 消息队列同步查询用 REST,异步事件用 MQ
设计原则SOLID财务规则多变,需易扩展

10.4 测试策略

实战要点
· 财务模块要求零缺陷上线,采用 V 模型——开发与测试一一对应;
· 数据迁移是高风险点,建立独立迁移测试环境;
· 老系统并行运行 3 个月,验证新系统稳定后才切换。

10.5 配置与质量管理

十一、软考考点总结与真题

11.1 核心公式速记

必背公式
1. McCabe 圈复杂度:V(G) = E - N + 2P (E 边数、N 节点数、P 连通分量数)
    简化:V(G) = 判定节点数 + 1 (单入单出程序)
2. 关键路径:总工期 = 最长路径长度;总浮动 = LS - ES = LF - EF
3. 测试用例数下限:等于圈复杂度 V(G)
4. 软件维护占比:完善性 ≈ 50%、适应性 ≈ 25%、改正性 ≈ 20%、预防性 ≈ 5%

11.2 高频考点清单

章节 高频考点
开发模型 九种模型特征、优缺点、适用场景;螺旋模型=风险驱动;RUP=用例+架构+迭代;瀑布=文档驱动
需求工程 需求分类(功能/非功能/约束);DFD 四要素与分层;需求跟踪矩阵
软件设计 内聚七种(功能最好);耦合七种(非直接最好);高内聚低耦合;SOLID 五原则
软件测试 覆盖标准强弱排序;圈复杂度公式;黑盒/白盒方法;集成测试策略
配置管理 SCM 四大功能;基线概念;CCB 变更控制;SVN vs Git
质量保证 ISO 9126 六特性;CMMI 五级;QA vs QC
项目管理 项目铁三角;关键路径计算;十大知识领域

11.3 真题演练

真题 1(开发模型选择)

某大型企业信息系统项目,需求明确、技术成熟、规模较大,但对质量要求极高,希望每个阶段都有严格评审。最适合采用哪种开发模型?

A. 螺旋模型  B. 瀑布模型  C. 增量模型  D. 快速原型

答案:B
解析:需求明确、技术成熟、要求严格评审,这是瀑布模型的典型适用场景。螺旋模型适用于高风险项目;增量模型适用于分批交付;快速原型适用于需求不明确。

真题 2(圈复杂度计算)

某程序控制流图有 16 条边、12 个节点、1 个连通分量。求该程序的圈复杂度 V(G),并说明至少需要多少个测试用例才能实现路径覆盖的下限。

答案:V(G) = 16 - 12 + 2×1 = 6
解析:根据 McCabe 圈复杂度公式 V(G) = E - N + 2P,代入 E=16、N=12、P=1,得 V(G)=6。圈复杂度等于程序中独立路径数,因此至少需要 6 个测试用例才能覆盖所有独立路径(路径覆盖的下限)。该模块复杂度属于中等(V(G) ≤ 10),可测试性较好。

真题 3(内聚与耦合)

某模块内含若干功能:读取数据、校验数据、计算结果、保存结果、打印报表。这些功能按固定顺序执行,前一功能输出作为后一功能输入。该模块的内聚类型属于哪种?如果该模块还直接修改了另一模块的内部变量,则耦合类型属于哪种?

答案:顺序内聚;内容耦合
解析:
1. 模块内功能按顺序执行,前一输出是后一输入,符合顺序内聚的定义(高强度内聚,仅次于功能内聚)。
2. 直接修改另一模块的内部变量,属于内容耦合——最强的耦合类型,应坚决避免。改进方法:通过接口/方法调用传递数据,改为数据耦合。

11.4 记忆口诀汇总

软考软件工程核心口诀
· 开发模型选型:需求明→瀑布;风险高→螺旋;需求变→敏捷/原型;分批交→增量;面向对象→喷泉;测试严→V 模型
· 内聚由低到高:偶逻时过通顺功
· 耦合由高到低:内公外控标数非
· 白盒覆盖强弱:语判条判组路(语句<判定<条件<判定/条件<条件组合<路径)
· ISO 9126 六特性:功可易效维移
· CMMI 五级:初管定量化优(初始-已管理-已定义-量化管理-优化)
· RUP 三特征:用例驱动 + 架构为中心 + 迭代增量
· 维护四类占比:完善最占(50%),预防最少(5%)

11.5 总结

软件工程是系统架构设计师考试的核心基础,贯穿上午综合知识、下午案例分析、下午论文三大题型。本章覆盖了从需求到维护的完整生命周期,重点包括:开发模型的选型(每种模型的特征、优缺点、适用场景)、需求工程的 DFD 与需求跟踪、软件设计的内聚耦合、软件测试的覆盖标准与圈复杂度、配置管理的变更控制、质量保证的 CMMI以及项目管理的进度与风险。

备考建议
1. 开发模型是每年必考,至少掌握 5 种模型的完整五要素;
2. 内聚/耦合的 7 种类型必须能排序 + 举例;
3. 圈复杂度公式必须能算会用,常出选择题;
4. CMMI 五级和 ISO 9126 六特性是背诵型考点,反复记忆;
5. 案例分析题常考需求变更管理、模型选型论证、测试用例设计,需结合实际场景作答;
6. 论文题若涉及软件工程,可围绕增量+敏捷的实践展开。

软件工程不是僵化的教条,而是一套权衡的艺术。架构师的价值在于根据项目特性,灵活选用合适的模型、方法和工具,在质量、成本、进度之间找到最佳平衡点。掌握了软件工程,就掌握了软件项目成功的"方法论"。