夜雨聆风学习资料网

ARTICLE · 1092656

01-软件工程概述

01-软件工程概述

第 1 章 软件工程概述

学习目标

  • 理解软件工程的定义与内涵
  • 了解软件危机的历史背景及其成因
  • 掌握软件工程三大支柱:方法、工具、过程
  • 熟悉软件的本质特征及其对工程的含义
  • 熟悉软件工程师的角色与核心能力
  • 理解软件开发中的经济约束

1.1 什么是软件工程

软件工程(software engineering):将系统化、规范化、可量化的方法应用于软件开发、运行和维护,即用工程原则构建高质量软件,并经济地利用上述经验研究软件工程技术。

这一定义包含三层含义:

  1. 方法论
    :开发活动遵循可重复、可验证的步骤,而非依赖个人灵感;
  2. 量化
    :质量、进度、成本可以被度量,因此可以被管理;
  3. 经济性
    :工程本质是"在约束下做权衡",不是追求技术上的完美。

软件工程的三大支柱

支柱
内容
例子
方法(methods)
需求分析、设计、测试的技术路线
UML 建模、TDD、静态分析
工具(tools)
支撑方法落地的自动化手段
IDE、Git、CI 服务器、测试框架
过程(process)
活动、任务、工件的组织方式
敏捷迭代、瀑布评审

三者关系:过程规定"做什么、何时做、产出什么";方法规定"怎么做";工具让方法可执行、可积累。

一个常见误区:把"上了工具"当成"工程化"。工具是放大器——过程混乱的团队上了 CI 只会更快地构建出混乱;方法缺失的团队买了最先进的测试平台,也只是把"没人设计用例"的问题自动化了。先有过程与方法,工具有意义。

与相关概念的边界

概念
与软件工程的关系
计算机编程
软件工程的一个子活动(编码),工程还包括需求、设计、验证、管理
计算机科学
研究计算本身的理论与算法;软件工程研究"如何在约束下产出可用的软件系统"
项目管理
工程的管理面(进度/成本/风险),不含技术方法本身
DevOps
把工程扩展到运行期的文化与实践,是工程思想的延伸

1.2 软件危机

20 世纪 60–70 年代,大型项目(如 S/360 配套软件、B-52 火控软件)超支、延期、质量低劣甚至酿成事故,史称软件危机。典型症状:

  • 成本与工期估算严重失真;
  • 用户不信任软件能否交付;
  • 软件质量无法保证;
  • 软件难以维护,维护成本远超开发成本;
  • 软件产量跟不上需求增长。

根本原因

  1. 软件本质上是逻辑产物而非物理实体
    :规模难以直观感知,复杂度增长非线性(认知复杂度);
  2. 软件必须与外部环境(硬件、OS、DB)保持一致
    ,任何一侧变化都可能引发回归;
  3. 软件易变性
    :需求、技术、法规持续变化;
  4. 缺乏工程管理
    :早期"程序员作坊"模式无法控制规模。

应对之道与历史脉络

时期
事件/思想
贡献
1968
NATO 软件危机会议
"软件工程"一词诞生,学科正式起步
1970s
结构化编程、结构化分析/设计
消除 goto,以结构控制复杂度;SADT、数据流图
1976
Boehm《螺旋模型》前身 COCOMO
成本估算模型化,风险显式化
1980s
面向对象、UML 前身
用封装/继承/多态组织大型系统
1990s
组件化、CMM(后 CMMI)
可复用构件;组织过程能力分级
2001
敏捷宣言
以反馈与适应应对需求不确定
2010s 至今
DevOps、云原生、SRE
工程闭环到运行期;基础设施代码化

规律:每次技术范式转移(结构化→OO→组件→云原生)都先于过程成熟。先解决"怎么写对",再解决"怎么管好"。

1.3 软件的本质特征(为什么软件难)

理解工程方法的前提,是理解被造物的属性。经典八特征:

特征
含义
工程含义
无形性
软件是逻辑结构,无法直观看到"进度"
进度管理依赖里程碑工件而非视觉进度
定制性
几乎每个系统都为特定业务定制
复用与标准化是降低成本的主要杠杆
依赖性
依赖硬件/OS/DB/网络/第三方服务
环境变化即回归风险;集成是高风险环节
复杂度
逻辑复杂度随规模超线性增长
抽象与模块化是控制复杂度的唯一手段
易变性
需求与技术持续变化
过程必须容纳变化(变更控制 + 迭代)
不稳定性
无物理磨损,但"逻辑磨损"(文档失实、知识流失)
维护是常态而非例外
开发环境多样
语言、平台、团队、组织差异大
过程需裁剪,不能一刀切
跨文化性
全球协作日益普遍
书面化、工具化、时区友好的沟通机制

核心推论:软件的复杂度是"认知复杂度"——它难在人的大脑,不在机器。因此软件工程的大量方法(评审、建模、小步、结对)本质上都是降低单次认知负荷、让多人共享同一心智模型的手段。

1.4 软件工程的三大活动

任何项目,不论规模与过程模型,都围绕三类活动展开:

规格(specification) → 开发(development) → 确认(confirmation)   "系统该做什么"     "把它做出来"        "验证做对了"
  • 规格活动
    :与客户沟通,获取并分析需求,产出 SRS(软件需求规格说明书);
  • 开发活动
    :设计、编码、单元测试、集成;
  • 确认活动
    :系统测试、用户验收、交付后反馈收集。

三大活动的展开视图

活动
典型任务
主要角色
关键工件
规格
干系人访谈、需求分析、用例建模、SRS 编写、需求评审
BA/PO、架构师
干系人矩阵、SRS、追溯矩阵
开发
架构设计、详细设计、编码、单元测试、集成
架构师、开发
架构文档、ADR、代码、单测
确认
测试设计、测试执行、缺陷跟踪、验收、上线观察
测试、BA、SRE
测试计划、缺陷库、测试报告

此外还有两个横切活动:

  • 软件项目管理
    (进度、成本、风险、人员)——贯穿始终;
  • 软件质量保证与过程改进
    (QA、审计、度量)——贯穿始终。

检验一个过程是否完整,就看这"三主两横"是否都有明确责任人与工件——无论叫瀑布、Scrum 还是 DevOps。

1.5 软件工程师的角色

角色
职责
关键产出
需求工程师/业务分析师
获取、分析、验证需求
SRS、用例模型
架构师
设计全局结构与技术选型
架构文档、ADR(架构决策记录)
开发工程师
详细设计与实现
代码、单元测试
测试工程师
测试设计与执行
测试计划、用例、缺陷报告
配置管理员
版本、基线、变更控制
构建产物、变更日志
项目经理
计划、协调、风险管理
项目计划、状态报告

小团队中角色高度合并,但职责不可缺席——每个活动都要有明确的责任人。

工程师的核心能力模型(软/硬结合)

能力
说明
培养方式
技术深度
语言、架构、测试方法的扎实功底
刻意练习 + 项目积累
抽象与建模
把混乱需求变成清晰结构
每项目强制画图/写 ADR
沟通与写作
需求澄清、评审、文档
文档即沟通
量化思维
用数据做决策,拒绝"感觉"
度量看板
权衡与取舍
在速度/质量/成本间做有依据的选择
复盘失败决策
职业伦理
不隐瞒缺陷、不夸大进度、保护用户数据
制度 + 文化

职业伦理要点:进度压力下的"报喜不报忧"是行业系统性风险;工程师对"这个缺陷上线会怎样"有独立陈述的责任,组织应建立无惩罚的缺陷上报机制。

1.6 核心原则(贯穿全系列)

  1. 抽象是控制复杂度的唯一手段
    :分层、模块化、接口化;
  2. 高内聚、低耦合
    :模块内部逻辑紧密,模块之间依赖最小;
  3. 单一事实来源(SSOT)
    :同一信息只在一处定义,他处引用;
  4. 尽早且持续地验证
    :缺陷发现越晚,修复成本越高(缺陷放大律);
  5. 一切可量化
    :进度、质量、风险都应基于数据决策;
  6. 为变化而设计
    :需求必然变化,架构应使变化代价最小;
  7. 文档是沟通媒介,不是存档负担
    :写给读者,保持"活文档"。

1.7 软件的经济性

  • 缺陷成本放大律
    :需求阶段的缺陷修复成本记为 1,设计阶段约 5–10 倍,编码阶段约 20–30 倍,测试阶段约 50–100 倍,上线后 100 倍以上(业界数据口径不一,量级关系成立);
  • 帕金森定律在软件中的体现
    :给项目 3 个月它可能用 2 个月完成;给 1 年它也可能拖 1 年。计划应基于估算,而非期望压缩;
  • 二/八法则
    :约 20% 的模块贡献 80% 的缺陷与复杂度——重点投入测试与重构应基于度量数据,而非平均用力;
  • 规模经济不成立
    :10 人项目的方法不能简单放大到 100 人,沟通成本按 n(n-1)/2 增长。

经济视角的三个决策习惯

  1. 比较修复成本曲线
    :同一缺陷在哪个阶段发现?用放大律倒推"上游多花 1 小时值多少";
  2. 比较维护成本占比
    :初始开发 30% / 维护 70% 是常态,架构决策的回报在生命周期后 2/3 兑现;
  3. 比较技术债利息
    :欠债模块每次修改的附加成本,决定"现在还债还是继续展期"。

1.8 本系列的主角:OOS 订单管理系统

后续章节将反复使用同一个虚构案例便于连贯理解:

OOS(Order System):某零售企业的订单管理系统。核心业务:商品目录管理、购物车、下单(含库存校验与支付)、订单状态流转(待支付→已支付→发货→完成/取消)、退货与售后。技术约束:Web + 移动端,日均 10 万订单,需与 ERP、支付网关集成,SLA 99.9%。

这个系统"中等复杂度 + 高变更频率 + 强外部集成",足以暴露软件工程中几乎所有经典问题。

1.9 本章 FAQ

Q1:软件工程师和程序员的区别? 程序员关注"把这段代码写出来";软件工程师关注"在约束下交付正确的系统"——包含需求理解、设计权衡、验证、协作与文档。编码是手段,交付价值是目的。

Q2:小项目需要软件工程吗? 需要的是"原则"而非"全套流程"。10 行脚本不需要 SRS,但仍需要:明确意图(一句话需求)、边界测试、可追溯的修改记录。过程规模应与风险匹配。

Q3:AI 辅助编码会取代软件工程吗? 改变的是编码阶段的效率与分工(AI 生成、人验证),不改变的是:需求正确性、架构合理性、责任归属。AI 生成代码越多,"验证"与"责任"的权重越高,工程框架反而更重要。

1.10 常见反模式(第 1 章视角)

反模式
症状
对策
工具崇拜
买工具代替定过程
先定活动与工件,再选工具
英雄主义
成败依赖单个高手
知识显式化(文档/ADR/评审)
文档虚无
"代码即文档"当借口
区分:代码说明 how,文档说明 why
进度迷信
只问"什么时候好"
用里程碑工件回答,不用百分比
质量后补
先做完再测
验证左移,DoD 前置

1.10 软件工程的标准化与常见规范

软件工程有一批被广泛引用的标准,理解它们能帮你与供应商、审计方、监管机构对话:

标准
主题
用途
ISO/IEC 12207
软件生命周期过程
过程框架的"元标准",定义各过程及其关系
ISO/IEC/IEEE 29148
需求工程
需求获取/分析/验证/管理的活动与质量要求
IEEE 830(已并入 29148)
SRS 内容
经典 SRS 结构,至今仍常被合同引用
ISO/IEC 25010
产品质量模型
七大质量特性,验收与度量的依据
ISO/IEC 25000(SQuaRE)
质量要求与评价
25010 的扩展族:需求、度量、评价
CMMI
过程能力成熟度
组织过程改进的分级参考
GB/T 8566
中国版软件生存周期
国内合同与投标常见引用

使用建议:标准是裁剪的起点,不是照抄的模板。OOS 的 SRS 结构参考 29148,但按敏捷项目裁剪为"用户故事 + 验收标准 + 关键 NFR 表"。

1.11 软件工程活动体系展开(输入-任务-输出)

以 OOS 为例,把"三主两横"展开为可执行的检查表:

活动
输入
核心任务
输出(工件)
完成判据
需求获取
业务目标、干系人清单
访谈/观察/文档分析/工作坊
原始需求记录、干系人矩阵
关键干系人 100% 覆盖
需求分析
原始需求
建模、消解冲突、分类优先级
用例模型、NFR 清单
冲突清零、NFR 全部量化
需求规格
分析结果
编写 SRS、编号
SRS v1.0
通过评审,每条可验证
架构设计
SRS
风格选型、质量属性对策、ADR
架构文档、ADR 库
评审通过,NFR 有对策
详细设计
架构文档
类/接口/算法设计
类图、序列图、接口契约
可编码,无重大悬而未决
编码与单测
详细设计
实现 + 单元测试
代码、单测
CI 全绿,覆盖达标
集成
可编译模块
接口联调、契约测试
集成报告
接口缺陷清零
系统测试
集成版
功能 + NFR 专项
缺陷库、测试报告
准出标准达成(第 6 章)
验收
系统测试通过版
用户场景验证
验收报告
用户签字
项目管理
全程
计划/估算/风险/沟通
项目计划、风险登记册、状态报告
里程碑可验证
QA 与改进
全程工件与度量
评审、审计、度量、改进
审计报告、度量看板、改进计划
过程遵循度达标

使用方式:新项目启动时,把此表作为"过程裁剪工作底稿"——逐行回答"本项目做不做、谁负责、产出什么、何时完成"。裁剪是显式决策,不是默认遗忘。

1.12 延伸 FAQ

Q4:软件工程的"过程"会被 AI 改变吗? 活动的内容会变(AI 辅助生成/验证),但责任结构不变:谁确认需求正确、谁为架构负责、谁验证行为符合预期。过程模型描述的正是这种责任与工件的流动,因此框架稳定,节奏加快。

Q5:学完本章,我下一步该做什么? 做三件事:(1) 用 1.11 的表描述你所在项目的现状,标出缺失的行;(2) 找一个你项目中的"缺陷放大"实例,估算它在不同阶段发现的成本差;(3) 读第 2 章,给你的项目选一个过程模型并写下三条理由。


小结

  • 软件工程 = 工程方法 + 量化管理 + 经济性权衡,不是单纯"写代码";
  • 软件危机源于软件的高复杂性与可变化性,应对之道是工程化;
  • 软件八特征(无形/定制/依赖/复杂/易变…)决定了工程手段的形态;
  • 所有项目都包含规格、开发、确认三类活动,外加项目管理与 QA 两个横切活动;
  • 核心原则:抽象、内聚/解耦、持续验证、可量化、为变化而设计;
  • 经济性三决策:缺陷成本曲线、维护占比、技术债利息。

思考题

  1. 为什么说"软件危机"不是某个公司管理不善,而是软件本身的属性决定的?
  2. 方法、工具、过程三者的关系是什么?缺任何一样会发生什么?
  3. 用"缺陷成本放大律"解释:为什么需求评审的 2 小时比多写 2 行代码"更值钱"?
  4. 在 3 人创业团队中,本章列出的角色如何分工?哪些职责可以合并,哪些绝对不能缺席?
  5. 软件的"认知复杂度"与"规模"什么关系?举一个"代码量很小但极难维护"的例子并分析原因。
  6. 从本章八特征中任选三条,分别推导出一条工程实践(例如"依赖性→集成测试"的推导过程)。
  7. 如果向一位只写过脚本的应届生解释"为什么需要软件工程",你会用哪三个论据?
  8. AI 生成代码占比超过 50% 后,你认为"确认"活动(验证)会如何变化?给出两条具体预测。
  9. 用 1.11 的活动体系表,为你当前项目做一张"现状-差距"对照:哪一行缺失工件?哪一行没有明确 Owner?写出你的前三项补强动作。
  10. 选择 1.7 的三个经济决策习惯之一,在你的项目中找一个真实场景,定量(或半定量)地演练一次决策过程,并写出结论。

相关学习资料