Informatics 43 — 第二周课堂笔记
目录
1. 软件失败案例
1.1 失败背后的真正原因
课程阅读材料指出了软件项目失败的几个根本原因:复杂性、一致性(必须与现有的人类系统集成)、难以衡量进度、"遗留"系统的负担,以及"哈勃心理学"(过度自信或群体思维使团队无法看到问题)。
哈勃心理学(Hubble Psychology) — 以哈勃太空望远镜命名 — 指的是一种信念:只要持续向一个失败的项目投钱,它最终就会成功。哈勃望远镜在开发期间曾被视为巨大的失败(国会投入了数百万美元,NASA 不断要求追加预算),但最终成为了一项巨大的成功。其他例子:Amazon 曾连续多年亏损大于盈利,但最终扭转了局面。然而,大多数抱有这种心态的项目只会走向失败 — 比如加州 DMV 现代化项目花费了 1.34 亿美元后被整个废弃。过度乐观是危险的;软件失败应该被预期,为失败做好规划才是关键。
1.2 案例研究:Minnesota 车辆登记系统
Minnesota 的车辆登记系统失败的原因在于团队从未明确定义各自的角色以及软件应该是什么。项目严重超预算,计划一次又一次地被修改。HP 被外包承接了这个项目,但最终基本上撤出了。这是一个典型的需求问题加上管理不善的案例 — 团队根本不知道自己在构建什么。
1.3 案例研究:TSB 银行
TSB 是一家英国银行,试图从一个基础设施迁移到另一个。在切换当天,客户无法登录或取款。能够登录的人发现余额出错 — 有些人没钱了,有些人多了钱,有些人甚至能访问别人的账户。这是软件迁移可能出错的最极端案例之一。
1.4 案例研究:Shopa
Shopa 是一家英国创业公司,最终关闭的根本原因在于公司始终没有弄清楚应该开发什么产品。内部团队对产品方向没有达成共识,导致工程团队和销售团队之间产生冲突。这是一个典型的需求缺失或不清晰时会发生什么的教科书级案例。

1.5 行业统计数据
| 统计数据 | 来源 |
|---|---|
| 仅 50% 的 IT 项目能在预算内按时交付;成本超支平均翻倍;34% 延期交付 | Jurgen Laartz |
| 仅 29% 的项目被认为成功;52% 为"受挑战"状态;19% 失败;每年浪费数十亿美元 | 2015 CHAOS 报告 |
| 最常报告的缺陷原因是需求问题(遗漏、变更或错误) | Kassab, DeFranco, LaPlante (IEEE SW 2017) |
1.6 软件失败的主要原因
软件项目失败的主要原因包括:
- 缺乏用户输入/参与 — 最常被提及的问题
- 不完整的需求和规格说明 — 需求问题
- 不断变更的需求和规格说明 — 需求问题
- 开发流程缺乏纪律 — 缺乏严谨性/规范性
- 缺乏系统性的度量方法 — 缺乏严谨性/规范性
- 资源不足
前三项都属于需求问题。中间两项反映了缺乏严谨性和规范性 — 这正是 INF 43 第一周提出的核心原则之一。
2. 需求为何至关重要
2.1 定义
一个重要区分:需求关注的是客户需要什么,而非客户想要什么。
"更快的马"类比: 客户说他想要一匹更快的马。为什么?因为他需要更快的交通方式。最终的最佳方案是造一辆汽车 — 客户从未要求过,但恰恰是他真正需要的。永远要深入挖掘表面需求背后的真实需要。
2.2 其重要性的证据
糟糕的需求是项目失败或受阻最常见的单一原因。根据 CHAOS 报告,需求缺陷导致的返工成本占总返工成本的 70% 以上,而返工本身大约消耗项目总预算的 30–50%。缺乏用户输入和参与一直被列为最常见的问题。

2.3 软件生命周期成本
绝大部分软件成本产生在初始构建之后:
| 阶段 | 占总成本比例 |
|---|---|
| 分析 | 2% |
| 规格说明 | 5% |
| 设计 | 6% |
| 模块编码 | 5% |
| 模块测试 | 7% |
| 集成 | 8% |
| 维护 | 67% |

2.4 变更成本随时间增长
在分析和规格说明阶段,变更成本最低。随着进入设计、实现、集成,尤其是维护阶段,成本会急剧上升。因此,在需求阶段多投入时间能在后期节省巨大成本。

2.5 在美国,哪个类别雇佣了最多的程序员?
A. 为内部使用编写系统的企业内部员工。 大多数程序员并不在游戏公司或消费级应用公司工作——他们构建的是内部业务系统。
3. 需求工程
3.1 瀑布模型中的需求阶段
在瀑布模型中,需求阶段是第一个阶段。它分为两个子活动:
| 子活动 | 含义 |
|---|---|
| 需求分析 | 发现、观察和收集客户需要的活动 |
| 需求规格说明 | 描述和记录客户需要的活动;也指由此产生的文档 |
扩展瀑布模型的流程为:需求分析 → 需求规格说明 → 设计 → 实现 → 验证 → 维护。

3.2 需求分析技术
有许多方法来发现系统应该做什么:
- 访谈客户 — 直接询问
- 观察客户 — 观察他们实际如何工作
- 创建用例/场景/用户故事 — 逐步描述交互过程
- 原型方案 — 快速构建原型以获取反馈
- 识别重要的对象、角色、功能、目标
- 进行调研 — 研究相关领域
- 构建模型 — 创建抽象表示
- 数据驱动分析 — 使用分析、A/B 测试、原型和市场调研来评估潜在功能
3.3 待办事项应用示例
课堂通过"给我做一个待办事项应用"的场景来展示模糊需求如何演变为精确需求。第一版仅有六条基本需求。改进版增加了排序、字符限制、删除撤销、可用性目标(无需培训即可在 5 分钟内完成任务)、日历集成和社交分享功能。
好的需求应当是:完整的、无歧义的、无冲突的和可验证的。
4. 需求规格说明文档
4.1 目的
需求规格说明文档是客户与软件开发方之间的基本参考依据。它定义了"做什么"(而非"怎么做")、环境约束、软件约束和软件质量要求。
值得在这份文档上花费大量时间,因为它是软件生命周期后续所有步骤的基础,而且现在做变更的成本远低于以后。
4.2 需求文档的使用者
许多不同的利益相关者会阅读此文档:客户、开发人员、管理者、测试人员、文档编写者、维护人员、系统工程师、软件架构师、市场营销人员等。
4.3 文档结构
| 章节 | 包含内容 |
|---|---|
| 引言 | 文档内容、谁创建的、为谁编写、文档大纲 |
| 执行摘要 | 简短(≤1 页)的主要目标、关键功能、主要风险/障碍描述 |
| 应用上下文 | 使用场景(家庭、办公室等)以及系统影响的所有事物(对象、流程、其他软件、硬件、人员) |
| 环境需求 | 平台(硬件:操作系统、内存、磁盘;软件:Web/移动/桌面、开源 vs 企业级)、编程语言、标准 |
| 功能需求 | 系统提供给用户的所有概念、功能、特性和信息。系统应该做什么?需要什么信息?出错时怎么办? |
| 软件质量(非功能需求) | 各种"...性":正确性、可靠性、效率、可用性、可维护性、可移植性、可重用性、互操作性、健壮性、安全性、可扩展性等。帮助开发人员评估实现权衡。 |
| 其他需求 | 成本、文档、手册、教程、培训以及其他不适合放在别处的内容 |
| 时间计划 | 交付日期(初始、验收期、最终)、里程碑(原型、设计完成、迭代周期) |
| 潜在风险 | 可能导致损失的未来不确定事件:新方法论、不熟悉的需求、资源短缺、激进的进度、紧张的资金、安全性、伦理问题 |
| 假设 | 项目生命周期中被认为成立的因素(最终用户特征、技术基础设施、资源/资金可用性)。如果假设发生变化,项目结果可能受损。 |
| 未来变更 | 预期的变更;文档结构应能吸收这些变更(一次性定义概念、分离关注点、避免冗余) |
| 术语表 | 文档中使用的术语的精确定义 |
| 参考文献 | 指向现有流程/工具、类似软件、文献的链接 |
| 用户界面 | 通常会包含一个大致的 UI 设计 |
| 验收测试计划 | 规定如何验证每项需求;约束客户在系统通过所有测试后接受系统 |
4.4 与 INF 43 原则的关联
需求文档本身的结构体现了软件工程的基本原则:严谨性、关注点分离(模块化、抽象)、预见变化、通用性和增量性。不是每个项目都需要文档中的每个章节。
5. 规格说明方法与验证
5.1 规格说明方法
| 方法 | 示例 |
|---|---|
| 自然语言 | SRS(软件需求规格说明)、用户故事 |
| 图表 | 数据流图、有限状态机、Petri 网 |
| 形式化语言 | Z、TLA+ |
| 模型 | 领域模型(对象)、使用模型(用例)、目标模型 |
5.2 验证清单
验证需求规格说明时,应检查:
- 是否完整?
- 每项需求是否可理解?
- 每项需求是否无歧义?
- 需求之间是否存在冲突?
- 每项需求是否可以验证?
- 所有术语和概念是否已定义?
- 规格说明是否无偏见?
6. Ziv 定律
Ziv 定律指出,软件开发是不可预测的,需求等文档化产物永远不会被完全理解。不确定性是软件工程过程和产品中固有且不可避免的。
这并不意味着需求是无用的——而是说我们应该预期不完美并为变化做好规划,这直接对应了预见变化这一原则。
7. 总结与记忆框架
第二周知识结构
|
+-- 软件失败
| +-- 根本原因:复杂性、一致性、进度衡量、遗留系统、过度自信
| +-- 哈勃心理学:过度乐观(Amazon、加州 DMV 1.34 亿美元浪费)
| +-- 案例研究:Minnesota(角色未定义)、TSB(迁移灾难)、Shopa(无明确产品方向)
| +-- 统计数据:29% 成功率、34% 延期、成本超支翻倍
| +-- 失败主因 → 主要是需求问题 + 缺乏严谨性
|
+-- 需求为何重要
| +-- 定义:做什么(不涉及怎么做);需要(不是想要)
| +-- "更快的马"类比:挖掘表面需求背后的真实需要
| +-- 70%+ 的返工成本源于需求缺陷
| +-- 变更成本随项目阶段指数级增长
| +-- 维护 = 总生命周期成本的 67%
|
+-- 需求工程
| +-- 分析:发现/观察/收集客户需要
| +-- 规格说明:描述/记录客户需要
| +-- 分析技术:访谈、观察、用例、原型、数据驱动
| +-- 好的需求:完整、无歧义、无冲突、可验证
|
+-- 需求规格说明文档
| +-- 目的:客户与开发方之间的基本参考依据
| +-- 章节:引言、执行摘要、应用上下文、
| | 环境需求、功能需求、软件质量、
| | 其他需求、时间计划、风险、假设、未来变更、
| | 术语表、参考文献、用户界面、验收测试计划
| +-- 结构体现 INF 43 原则
|
+-- 规格说明方法
| +-- 自然语言、图表、形式化语言、模型
| +-- 验证:完整、无歧义、无冲突、可验证、已定义、无偏见
|
+-- Ziv 定律
+-- 不确定性在软件工程中固有且不可避免
+-- 需求永远不会被完全理解
+-- 为变化做好规划一句话总结
需求工程——系统性地分析和规定软件应该做什么——是开发过程中最关键的阶段,因为需求缺陷是项目失败的首要原因、后期修复成本最高,而且文档结构本身也必须体现贯穿整个学科的软件工程原则(严谨性、关注点分离、预见变化)。