我已经相信这里没有提到过关于重构的一些东西,我知道这里已经有很多答案了,但是我认为这是新的。
自从条款出现之前,我一直是无情的重构者和DRY的坚定拥护者。这主要是因为我难以保持较大的代码库,部分原因是我喜欢DRY编码,而对C&P编码则一无所知,实际上这对我来说是痛苦的,而且非常缓慢。
问题是,坚持使用DRY在一些我很少见到的其他技术上给了我很多实践。许多人坚持认为Java很难或不可能进行DRY,但实际上他们只是不尝试。
很久以前的一个例子与您的例子有些相似。人们倾向于认为Java GUI的创建很困难。当然是这样的代码:
Menu m=new Menu("File");
MenuItem save=new MenuItem("Save")
save.addAction(saveAction); // I forget the syntax, but you get the idea
m.add(save);
MenuItem load=new MenuItem("Load")
load.addAction(loadAction)
任何认为这太疯狂的人都是绝对正确的,但这不是Java的错-绝不应该这样编写代码。这些方法调用是旨在包装在其他系统中的函数。如果找不到这样的系统,请构建它!
您显然不能像这样编写代码,因此您需要退后一步看看问题,重复的代码实际上在做什么?它指定一些字符串及其关系(一棵树),并将该树的叶子连接到动作。因此,您真正想要的是说:
class Menu {
    @MenuItem("File|Load")
    public void fileLoad(){...}
    @MenuItem("File|Save")
    public void fileSave(){...}
    @MenuItem("Edit|Copy")
    public void editCopy(){...}...
一旦您以简洁明了的方式定义了关系,就编写了一种处理该关系的方法-在这种情况下,您遍历传入的类的方法并构建一棵树,然后使用该树来构建菜单和操作以及(显然)显示菜单。您将没有重复,并且您的方法是可重用的……与许多菜单相比,它可能更容易编写,而且,如果您实际上喜欢编程,那么您会感到很多乐趣。这并不难-您需要编写的方法可能比手工创建菜单所需的行少!
事情是,为了做到这一点,您需要练习很多。您需要善于准确分析重复部分中的独特信息,提取该信息并弄清楚如何很好地表达它。学习使用诸如字符串解析和注释之类的工具会很有帮助。学会弄清错误报告和文档记录也很重要。
只需编写良好的代码,即可获得“免费”练习-碰巧的机会是,一旦您熟练掌握了代码,就会发现对DRY进行编码(包括编写可重用的工具)比复制和粘贴以及所有错误,重复错误更快以及编码类型造成的困难变化。
如果我没有尽可能多地练习DRY技术和构建工具,我认为我将无法享受工作。如果我不得不削减工资而不必进行复制和粘贴编程,那我会接受的。
所以我的观点是:  
- 除非您不知道如何正确重构,否则“复制粘贴”将花费更多时间。
- 您会通过这样做来学会重构,即使在最困难和琐碎的情况下也要坚持使用DRY。
- 您是一名程序员,如果您需要一个小的工具来使您的代码DRY,请对其进行构建。
 
              
always和never红色标志。有一个叫做“上下文”的东西,其中always和never规则,即使总的来说很好,也可能不合适。当心那些绝对的软件开发人员。;)