🧩 第三章 理解OOP:编程语言的历史
📄 一句话概括

结构化最后一块短板能精确量出来:40 个函数配 12 个全局变量=480 条依赖边。

📝 本节和前面几节的关系

3.8 说了方向,这一节收口:问题具体在哪,OOP 又是怎么接手的。

一、依赖边

n 个函数各自访问 k 个全局变量,潜在依赖边就是 n×k。 实测:5 个函数配 3 个全局变量是 15 条边;40 个配 12 个,就是 480 条。 改一个全局变量的含义,理论上要检查 480 条边。 这就是【结构化没有解决全局变量问题】的具体含义:它规整了流程,没管住数据。

二、可重用性为什么差

函数能复用,但它要的数据得从外面传进来。 而这些数据往往藏在全局变量里——带不走。 所以要复用那段逻辑,就得连全局变量一起搬——搬不动,只好复制。 复制一多,就回到 3.6 说的那个坑:改一处漏三处。

三、OOP 的两刀

第一刀:封装。把数据关进类里,只留几个入口——依赖边被切断。 第二刀:继承与组合。让数据和规则一起被复用——数据带得走了。 这两刀正好砍在 3.8 列的四个短板上。 所以第 4 章紧接着讲类的三个功能,第一个就是汇总。

四、这一章的结论

语言史走了一条清晰的线:机器码 → 汇编 → 高级语言 → 结构化 → OOP。 每一步都不是因为前一步错了,而是因为前一步把规模推上了新台阶。 OOP 解决的是【数据被谁改】和【代码怎么带得走】这两个问题。 下一章开始拆 OOP 的三个结构——那才是这门课的正题。

五、动手 Demo:没有解决全局变量问题和可重用性差的问题

把全局变量带来的依赖边数算出来。 这个数能解释:为什么结构化之后,复用还是那么难。

for n, k in ((5, 3), (10, 5), (20, 8), (40, 12)):
    print(n, "个函数 ×", k, "个全局变量 →", n * k, "条依赖边")
print("改一个全局变量,理论上要检查", 40 * 12, "条边")

实跑输出:

--------------------------------------------------------------------
没有解决全局变量问题和可重用性差的问题
--------------------------------------------------------------------

  结构化编程的最后一块短板,可以精确量出来:**全局变量的耦合边数。**
  **n 个函数各自访问 k 个全局变量,潜在依赖边就是 n×k。**

  函数数     全局变量数     依赖边
  ---------------------------------
  5          3              15
  10         5              50
  20         8              160
  40         12             480

  实测:**40 个函数配 12 个全局变量,就有 480 条依赖边。**
  **改一个全局变量的含义,理论上要检查 480 条边。**
  这就是 3.9 说的【没有解决全局变量问题】——**结构化只规整了流程,没管住数据。**

  可重用性差的原因也在这儿:

      函数能复用,但它要的数据得从外面传进来
      而这些数据往往藏在全局变量里 —— 带不走

  **OOP 的两刀正好砍在这两处:**
  **封装把数据关进类里(切断依赖边)**,**继承和组合让数据和规则一起被复用。**
  第 4 章开始讲这两刀具体怎么下。

实测:40 个函数配 12 个全局变量,480 条依赖边。 OOP 的两刀砍在这两处:封装切断依赖边,继承与组合让数据带得走。

30 秒实验

  1. 数一数你项目里的全局变量,估算一下依赖边有多少条。
  2. 把一组全局变量收进类,看依赖边能不能降下来。

常见误区

  1. 以为结构化编程已经解决了复用。数据带不走,复用就不成立。
  2. 以为 OOP 是对结构化的否定。它是继承并放大。
自测三问(点开对答案) 1. 依赖边怎么算? —— n 个函数各访问 k 个全局变量,潜在依赖边是 n×k;40 个函数配 12 个变量就是 480 条。 2. 为什么全局变量让复用变难? —— 函数要的数据藏在全局变量里,带不走;要复用就得连全局变量一起搬,搬不动只好复制。 3. OOP 的两刀是什么? —— 封装把数据关进类里、切断依赖边;继承与组合让数据和规则一起被复用。

相关笔记