再见,clean code(2020)
许多工程师认为,严格套用“clean code”原则,如 DRY 和激进抽象,可能适得其反:它们会降低灵活性,让未来修改更困难而不是更容易。评论者对比了重复但直接、面向领域的代码,与把无关情况纠缠在一起的抽象版本,后者往往提高认知负担,并常常反映了在例子过少时就急于泛化的冲动。一个反复出现的主题是:可维护性既取决于良好的判断、沟通和结合上下文的权衡,也取决于任何具体风格规则或设计教条。
Clean Code、DRY 与抽象
- 许多人认为,这次重构之所以失败,是因为它产生了一个 糟糕的抽象,而不是因为“clean code”本身有问题。
- DRY 被视为一条指导原则:当多个地方应该始终一起变更时,它很有价值;当它迫使无关的情况走进同一条路径时,它就有害。
- 几条评论强调“自底向上抽象,而不是自顶向下”:先让具体用例积累起来,然后再提炼出简单、显而易见的辅助函数。
- 一个反复出现的经验法则是:对 知识 或行为的重复值得抽象;而代码形状上的表面相似通常不值得。
何时重复更可取
- 多位发言者说过,“重复比错误的抽象更便宜。” 错误的抽象会变得脆弱,加入条件分支和特殊情况,而且很难拆掉。
- 对于不断演化的领域(图形、金融产品、复杂业务逻辑),保留彼此分离但相似的代码路径,往往能为未来的分化保留灵活性。
- 有人指出,修改几个地方的同一逻辑,往往并不是实际成本驱动因素;更常见的是,调试一个纠缠不清的抽象才是。
评估“Clean Code”经典体系
- 有人批评“Clean Code”式风格过于教条、缺少限定条件,而且很容易吸引初学者机械套用规则(例如,“大量很小的函数”、不惜一切代价 DRY)。
- 也有人指出,原始文本把建议描述为有争议且非权威的,并坚持误用是读者的问题,不是书的问题。
- 有人担心,lint 工具和团队把灵活的指导原则变成了僵硬的教条。
团队动态与流程
- 许多人认为,核心错误其实是社会/流程层面的:在夜里重写同事刚完成的工作,并且未讨论、未审查就直接提交。
- 对此看法分成两派:“代码属于团队;任何人都可以重构” 与 “上下文和礼节很重要;单方面重写会破坏信任。”
- 建议的替代方式包括:审查评论、渐进式提取辅助函数、以原作者参与的独立 PR 进行。
语言与范式视角
- 一些人称赞函数式语言(例如具有 Applicative/Monad 定律的语言)提供了标准化、可复用的抽象,从而减少项目特有抽象。
- 另一些人强调 Go 的相反取舍:较少的语言级抽象、更多重复,但心理模型更简单。
- 关于面向对象的几何层次结构(例如正方形与长方形)以及可变性如何破坏天真的抽象,仍有争论。
测试、可维护性与实用性
- 有一派认为,充分的测试本可以支持“无畏重构”,并让这次修改变得毫无争议。
- 另一些人回应说,测试并不能解决认知复杂度或社会问题;在美学上或结构上糟糕的代码即使被完全测试过,依然有害。
- 一个广泛共识是:可维护性、业务逻辑清晰度和修改便利性,应高于美学或行数减少。