优先选择重复,而不是错误的抽象(2016)

争论范围:重复 vs. 抽象

  • 许多人认同核心观点:过早或“错误”的抽象,可能比少量、局部的重复更有破坏性。
  • 也有人反驳说,大规模重复可能会变成灾难,尤其是在生命周期长、面向多客户或多团队的系统中。
  • 几位评论者认为这句口号常被误读;它的意思是避免过早或偶然的抽象,而不是允许一直复制粘贴下去。

什么时候重复是有用的

  • 重复的实现可以作为发现正确抽象的一种工具:“写两次或三次,然后再重构”(三次法则 / WET)。
  • 在业务需求和领域边界仍不清晰时,重复通常被视为更便宜、更安全的早期选择。
  • 有些人更喜欢彼此隔离、略有重复的流程,而不是一个带着许多标志位和条件分支的脆弱“上帝抽象”。

抽象何时会出错

  • 例子包括:过度通用的框架、被强行引入的多态、微服务中的“分布式单体”、重度使用 Redux 的前端,以及把 DRY 推到极端。
  • 错误的抽象往往会:
    • 编码偶然相似性,而不是真正共享的概念。
    • 扩散隐藏耦合,使每次改动都变得有风险且影响全局。
    • 积累布尔/配置参数和复杂的调用链。
  • 有人认为,任何可维护的抽象都比超过“微不足道”规模后的广泛重复更好;也有人强烈不同意。

经验法则和启发式规则

  • 常见经验法则:
    • 不要在只出现一次时就抽象;在第二次出现时考虑;在第三次出现时行动,前提是它们确实代表同一个概念,并且因为同样的原因而变化。
    • 偏好那些从自身接口就显而易见、足以自圆其说的抽象,而不仅仅依赖对调用方的了解。
    • 倾向于松耦合和简单的支撑库,而不是深度集中、聪明但复杂的框架。
    • 为了未来替换的便利而抽象,而不是为了推测性的复用。

LLM 与成本曲线

  • 有人指出,LLM 让重复更便宜地创建和重构,可能把权衡推向更简单、重复更多的代码。
  • 也有人反馈,LLM 会带来更多重复,而且在重构时可能漏掉所有实例,因此抽象仍然重要。
  • 普遍观点是:AI 改变了经济成本,但并没有消除思考抽象与重复之间取舍的需要。