OOP 不是被【发明】出来的,是被规模逼出来的:函数从 5 个涨到 80 个,潜在干扰对从 10 涨到 3160。
第一章讲它是什么,第二章拆了比喻,这一章从语言史看这些概念为什么必须出现。
一、先算一笔规模账
一堆函数共享一批全局变量,任意两个函数都可能通过它互相影响。 这种潜在干扰对是 n×(n-1)÷2,随函数数平方增长。 实测:函数 5 个时 10 对,80 个时 3160 对——函数涨 16 倍,风险涨 316 倍。 规模一大,靠【大家都小心点】就撑不住了。
二、为什么是必然
软件不会停在五个函数。需求一涨,代码量就涨,人却还是那几个。 这时候只有两条路:要么限制规模(做不到),要么发明新结构(只能做这个)。 OOP 提供的正是这个结构:把数据关进盒子,盒子的主人只有一个。 干扰对不再按函数的平方长,而是被类的边界切断。
三、每一次进化都因为上一层的天花板
机器码太硬 → 有了汇编。汇编解决了记不住的问题。 汇编太碎 → 有了高级语言。高级语言解决了换平台的问题。 高级语言太乱 → 有了结构化编程。结构化解决了读不懂的问题。 结构化管不住数据 → 有了 OOP。OOP 解决的是【数据被谁改】的问题。 这条链上每一环,都是被上一环的短板逼出来的。
四、这一章要回答的问题
为什么书要从机器码讲起?因为不理解每一层在解决什么,就记不住下一层为什么存在。 这一章按时间走九节:机器码 → 汇编 → 高级语言 → 结构化 → 无 GOTO → 子程序 → OOP。 读的时候只要盯住一件事:这一步替上一层接过了什么麻烦。
五、动手 Demo:OOP 的出现具有必然性
算一笔规模账:n 个函数共享全局变量时,潜在干扰对有多少。 这个数按平方增长,正好解释 OOP 为什么必须出现。
for n in (5, 10, 20, 40, 80):
pairs = n * (n - 1) // 2
print(n, "个函数 →", pairs, "对潜在干扰")
实跑输出:
--------------------------------------------------------------------
OOP 的出现具有必然性
--------------------------------------------------------------------
先算一笔账:**一堆函数共享一批全局变量,风险有多大?**
任意两个函数都可能通过全局变量互相影响——
**这种【潜在干扰对】的数量是 n×(n-1)÷2,随函数数平方增长。**
函数数 潜在干扰对 说明
---------------------------------------
5 10 对 还能靠人记住
10 45 对 开始吃力
20 190 对 开始靠自觉
40 780 对 只能靠运气
80 3160 对 只能靠运气
实测:**函数从 5 个涨到 80 个(16 倍),干扰对从 10 涨到 3160(316 倍)。**
**规模一大,靠【大家都小心点】是撑不住的。**
这就是 OOP 出现的必然性:**它不是为了优雅,是为了让规模可控。**
类的做法是把数据关进盒子里(1.2),**盒子的主人只有一个**——
于是干扰对不再按函数的平方长,而是**按类的边界被切断**。
实测:5 个函数 10 对,80 个函数 3160 对——函数涨 16 倍,风险涨 316 倍。 OOP 不是为了优雅,是为了让规模可控:盒子的主人只有一个,干扰对被边界切断。
30 秒实验
- 数一数你的项目里有多少全局状态,再想想它被多少个函数改过。
- 把其中一组全局变量收进一个类,看调用方要改几处。
常见误区
- 以为 OOP 是某人灵机一动的发明。它是被规模逼出来的。
- 以为全局变量只是【不优雅】。它带来的是平方级的干扰面。
自测三问(点开对答案)
1. n 个函数共享全局变量,潜在干扰对是多少? —— n×(n-1)÷2,随函数数平方增长;实测 5 个函数 10 对,80 个函数 3160 对。 2. 为什么说 OOP 的出现是必然的? —— 软件规模必然增长,靠人小心撑不住;要么限制规模(做不到),要么发明新结构(只能做这个)。 3. OOP 切断干扰对的办法是什么? —— 把数据关进类里,只留几个入口,盒子的主人只有一个。- ☐ 下一节(3.2 最初使用机器语言编写程序)
相关笔记
- 没有解决全局变量问题和可重用性差的问题 — 这一章的落点
- 以对象为中心编写软件的开发方法 — 盒子是怎么关上的
- 🔵 计算机基础 · 索引 — 机器码与汇编的基础
- 🧩 面向对象是怎样工作的 · 索引