优先选择重复,而不是错误的抽象(2016)
争论范围:重复 vs. 抽象
- 许多人认同核心观点:过早或“错误”的抽象,可能比少量、局部的重复更有破坏性。
- 也有人反驳说,大规模重复可能会变成灾难,尤其是在生命周期长、面向多客户或多团队的系统中。
- 几位评论者认为这句口号常被误读;它的意思是避免过早或偶然的抽象,而不是允许一直复制粘贴下去。
什么时候重复是有用的
- 重复的实现可以作为发现正确抽象的一种工具:“写两次或三次,然后再重构”(三次法则 / WET)。
- 在业务需求和领域边界仍不清晰时,重复通常被视为更便宜、更安全的早期选择。
- 有些人更喜欢彼此隔离、略有重复的流程,而不是一个带着许多标志位和条件分支的脆弱“上帝抽象”。
抽象何时会出错
- 例子包括:过度通用的框架、被强行引入的多态、微服务中的“分布式单体”、重度使用 Redux 的前端,以及把 DRY 推到极端。
- 错误的抽象往往会:
- 编码偶然相似性,而不是真正共享的概念。
- 扩散隐藏耦合,使每次改动都变得有风险且影响全局。
- 积累布尔/配置参数和复杂的调用链。
- 有人认为,任何可维护的抽象都比超过“微不足道”规模后的广泛重复更好;也有人强烈不同意。
经验法则和启发式规则
- 常见经验法则:
- 不要在只出现一次时就抽象;在第二次出现时考虑;在第三次出现时行动,前提是它们确实代表同一个概念,并且因为同样的原因而变化。
- 偏好那些从自身接口就显而易见、足以自圆其说的抽象,而不仅仅依赖对调用方的了解。
- 倾向于松耦合和简单的支撑库,而不是深度集中、聪明但复杂的框架。
- 为了未来替换的便利而抽象,而不是为了推测性的复用。
LLM 与成本曲线
- 有人指出,LLM 让重复更便宜地创建和重构,可能把权衡推向更简单、重复更多的代码。
- 也有人反馈,LLM 会带来更多重复,而且在重构时可能漏掉所有实例,因此抽象仍然重要。
- 普遍观点是:AI 改变了经济成本,但并没有消除思考抽象与重复之间取舍的需要。