📄 一句话概括
重复不一定是整段复制,更多是同几行出现三次——实测 12 行代码里 3 种重复行占了 9 行;但长得像不等于重复,能不能一起改才算。
📝 本节和前面几节的关系
10.2 说了重心在改动成本,重复正是改动成本的最大来源——改一处要改三处。
一、重复的三种形态
整段复制:最明显,一眼能看出。 同样几行出现三次:最隐蔽,实测 3 种行各出现 3 次,占了 9 行。 结构重复:代码不一样但形状一样(三个子类各写一遍同样的校验)。
二、实测:12 行里 9 行是重复的
三个类各写一遍 if rate < 0: raise ...、self.rate = rate。
3 种重复行各自出现 3 次,合计 9 行——占 12 行的 75%。
每种只留一份是 6 行,加上三处调用约 9 行,看上去省得不多,但改动点从 3 处变 1 处。
三、关键判断:它们会不会一起改
会一起改,才叫重复。 那三处校验规则一变,三处都得改——这是真重复。 只是长得像、但会各自演化,那叫巧合。 硬合并反而害了它们:一个改了另一个不该改。 所以去重之前先问一句:这两个东西将来会一起变吗?
四、去重的三种手法
提取方法:把重复的几行提成一个函数。 提到父类:几个类共有的部分上移到父类(4.9 的继承)。 参数化:把不同的那一部分做成参数,剩下的共用。 手法选择看重复的粒度:几行用提取方法,几类共有用父类,只差一点用参数化。
五、动手 Demo:设计目标之一:去除重复
用 Counter 扫一段代码,找出出现不止一次的行。
数出重复行占了总行数的多少。
from collections import Counter
src = ["if rate < 0:", " raise ValueError('rate')",
"self.name = name", "self.rate = rate",
"if rate < 0:", " raise ValueError('rate')",
"self.title = title", "self.rate = rate",
"if rate < 0:", " raise ValueError('rate')",
"self.code = code", "self.rate = rate"]
dup = [(k, v) for k, v in Counter(src).items() if v > 1]
print(len(src), len(dup), sum(v for k, v in dup)) # 12 3 9
实跑输出:
--------------------------------------------------------------------
设计目标之一:去除重复
--------------------------------------------------------------------
重复不一定是整段复制,**更多是【同样的几行出现三次】。**实测扫描:
重复的行 出现次数
--------------------------------------
if rate < 0: 3
raise ValueError("rate") 3
self.rate = rate 3
代码行 12 行
重复出现的行 3 种
重复行占用 9 行
每种只留一份 6 行
加上三处调用 约 9 行
**3 种重复行占了 9 行**,提取一次就能省掉后面的复制。
**关键判断**:这三处改的时候是不是要一起改?**是要一起改,才叫重复。**
**只是长得像但会各自演化,那叫巧合**——硬合并反而害了它们。
实测:12 行里 3 种重复行各出现 3 次,共占 9 行。 每种只留一份是 6 行——省的行数不多,但改动点从 3 处变成 1 处。 判断标准是【会不会一起改】,只是长得像那是巧合。
30 秒实验
- 用同样的办法扫你自己的一段文件,找出重复行。
- 对每一处重复问一句:它们将来会一起改吗。
常见误区
- 以为只有整段复制才叫重复。同几行出现三次更常见也更隐蔽。
- 把长得像但各自演化的代码强行合并。那会害了它们。
自测三问(点开对答案)
1. 重复的三种形态? —— 整段复制、同几行出现三次、结构重复(形状一样但代码不同)。 2. 实测重复占多少? —— 12 行里 3 种重复行各 3 次,共 9 行;每种留一份是 6 行。 3. 判断重复的标准是什么? —— 将来会不会一起改——会一起改才是真重复,只是像叫巧合。- ☐ 10.4 设计目标之二:提高构件的独立性
相关笔记
- 相比运行效率,现在更重视可维护性和可重用性 — 为什么重复最贵
- 三大要素之三:去除类的重复定义的继承 — 提到父类那条路
- 设计目标之二:提高构件的独立性 — 下一个目标
- 🧩 面向对象是怎样工作的 · 索引