正如我在回答另一个问题时所说,我的方法如下:
- 第一次解决某个问题时,我就完成了。
- 第二次(即,当我解决类似的问题时),我想:嗯,也许我在重复自己,但现在我将进行快速复制和粘贴。
- 我第三次认为:嗯,我在重复自己->使它更笼统!
即直到2,另一项原则(YAGNI)胜过DRY。但是从3开始(如果我真的很懒的话,从4开始),看来我会需要它,所以我遵循DRY。
更新资料
从我最近的经验中可以得出一些进一步的想法。我必须将另一个团队开发的两个组件A和B适应/集成到我们的产品中。首先:两个组件A和B B彼此非常相似,因此,我已经为它们的体系结构有些不同而感到不安。第二:我必须适应它们,所以我很高兴使用子类并且仅覆盖我真正需要的东西。
因此,我开始重构这两个组件(每个组件都包含大约8个C ++类):我想为A和B拥有一个通用的体系结构,然后通过定义子类来添加我们需要的功能。这样,我们的两个新组件A'和B'将从现有组件中派生。
经过两周的尝试,试图从现有代码中获得一个通用且定义明确的结构,并不得不在日常会议上解释说,由于原始代码太乱,我的进步很小,然后我与老板交谈。我们观察到,除了这两个新组件A'和B'(不再需要其中的四个或六个,只有这两个)之外,我们将不需要任何其他东西。
好的,就是这样:我做了一个大规模的复制,并重命名了A和B中的类,并开始调整代码的副本。我让它在两周内可以正常工作(现在仍在进行一些错误修复)。
优点:我们的功能现在几乎已经完成,并且在修复所有错误之后,我们就完成了。我们已经保存了A和B的所有重构和测试。
缺点:两个星期前,另一个团队更改了另一个组件C,供A和B使用。他们改编了A和B,但A'和B'也坏了,我们必须自己更改它们。这引入了一个我们必须修复的新错误。如果A'和B'与A和B共享了大部分代码,那么这些额外的工作可能是不必要的。
因此:代码重复总是很危险的。我认为这总是要权衡取舍的问题,通常这并不容易。