编程的所有原则中,不要重复自我(DRY)或许是最基本的原则之一。该原则被Andy Hunt和Dave Thomas的《程序员修炼之道》一书中提出,便成了很多为知名软件开发的最佳实践和设计模式的基础。开发人员学习辨认副本,并理解如何通过适当的实践和抽象来消除这些重复,相比于一直被传染多余的重复代码的应用程序,可以产出更简洁的代码。
复制是种浪费
应用程序的代码中的每行代码都将会维护,也将会成为潜在的bug。重复会使代码库不必要的臃肿,结果让bug有机可乘,并增加系统的耦合度。重复的臃肿加入系统也会让开发者难以彻底理解系统全貌而,还有一点可以确定,另外为了确保它们能正常工作,修改了某处的逻辑也需要修改另一处的复制。DRY需要“系统内每处的知识都必须具有单一、明确、权威的表示”。
过程中的重复要自动化
很多软件开发中的流程都是简单而重复的自动化。DRY原则适用于这些应用程序源码中的上下文。手动测试太慢了,容易出错,也很难重复操作,所以如果可能的话,自动化测试套件应该被用起来。如果手动进行软件集成可能会耗时且容易出错,因此构建过程应尽可能频繁地运行,理想情况下每次签入(代码库)时都跑一遍。只要存在能被自动化的痛苦的人工流程,都应该被自动化和标准化。其目标是确保仅有唯一的方式来完成任务,并且要尽可能做到无痛。
逻辑中的重复要抽象
逻辑中的重复会有很多形式。复制粘贴if-then或switch-case逻辑是最容易检查并纠正的。很多设计模式都有明确的目标,要降低或消除应用程序中的重复。如果一个对象在使用前需要同时具备几个事情的发生,就可以用抽象工厂或者工厂方法来完成。如果一个对象的行为会有很多可能的变化,这些行为就可以通过策略模式来注入,要好于大量的if-then结构。事实上,设计模式本身的制定是为了降低常见问题带来的重复,并讨论这些解决方案。此外,DRY可以适用于数据结构,如数据库模式,从而更规范。
一个原则问题
其它的软件原则也和DRY相关。有且仅有一次原则,仅适用于代码功能行为,可以被认为是DRY的一个子集。开闭原则,“软件中的实体应对扩展开放,对修改封闭”的情况,仅在遵循DRY时才能在实践中起作用。同样众所周知的单一职责原则,需要一个类“只有一个改变原因”依赖于DRY。
当遵循结构、逻辑、流程、以及函数时,DRY原则能为开发人员提供基本指导,并帮助创建更简单,更易于维护,更高质量的应用。尽管有一些情况下,必须用重复来满足性能或其它需求(例如数据库中的非规范化数据),它应该被直接用于解决实际而非想象的问题。