你能容忍多less重复的代码?

在最近的代码审查中,我发现了一个类(less于15行)的几行重复的逻辑。 当我build议作者重构代码时,他认为代码更易于理解。 再次阅读代码后,我必须同意提取重复的逻辑会伤害可读性一点。

我知道DRY是指导方针,而不是一个绝对的规则。 但总的来说,你是否愿意以DRY的名义伤害可读性?

重构:改进现有代码的devise

三条法则

你第一次做某事,你就做。 你第二次做
类似的东西,你在重复,但你做重复
无论如何。 你第三次做类似的事情,你重构。

三次罢工,你重构。


编码在工作

Seibel:所以对于这些XII调用中的每一个,你都在写一个实现。
你有没有发现你积累了很多类似的代码?

Zawinski:哦,是的,当然。 通常在第二次或第三次你剪切和粘贴
那段代码就好像是时候停止剪切并粘贴到一个子程序中。

我没有容忍。 我可能会因为时间的限制或者什么而结束。 但是我还没有find真正保证重复代码的情况。

说这会伤害可读性只能表明你不好select名称:-)

就我个人而言,我宁愿保持代码的可理解性,首要的。

DRY是关于简化代码维护。 为了消除重复的代码,让代码不太可以理解,在许多情况下,比重复一些代码行更多地伤害可维护性。

这就是说,我同意DRY是一个很好的目标,在实践中。

如果有问题的代码具有明确的业务或技术支持目的P,则通常应该对其进行重构。 否则,您将遇到克隆代码的经典问题:最终您会发现需要修改支持P的代码,而且您不会find实现它的所有克隆。

有些人build议3个或更多的副本是重构的门槛。 我相信如果你有两个,你应该这样做; 在一个大的系统中发现其他的克隆(或者甚至知道它们可能存在)是很难的,无论你有两个还是三个或更多。

现在这个答案是在没有find克隆的工具的情况下提供的。 如果可以可靠地find克隆,那么重构(避免维护错误)的原始原因就不那么具有说服力(具有命名抽象的效用仍然是真实的)。 你真正想要的是一种查找和追踪克隆的方法; 抽象它们是确保你能“find”它们的一种方法(通过find微不足道的东西)。

可以可靠地查找克隆的工具至less可以防止出现故障更新克隆维护错误。 一个这样的工具(我是作者)是CloneDR 。 CloneDR使用目标语言结构作为指导来查找克隆,从而查找克隆,而不pipe空白布局,注释的变化,重命名的variables等等(它被实现为包括C,C ++,Java,C#,COBOL和PHP )。 CloneDR将在大型系统中find克隆,而不会给出任何指导。 显示检测到的克隆以及antiunifier ,这本质上是您可能写的抽象。 它的版本(用于COBOL)现在与Eclipse集成在一起,并显示在缓冲区中的克隆内部以及其他克隆所在的位置,以便您可以检查/修改其他克隆。 (你可能做的一件事是重构他们:)。

我曾经认为克隆只是彻头彻尾的错误,但人们这样做是因为他们不知道克隆将如何与原来的不同,所以最终的抽象在克隆行为发生的时刻并不清楚。 现在我相信克隆是好的,如果你能跟踪克隆,并且在抽象变得清晰之后你试图重构。

只要你重复了任何你创build了多个地方,如果你发现你犯了一个错误,需要进行编辑,需要扩展,编辑,删除或其他几十个其他原因,你可能会遇到这种情况迫使改变。

在大多数语言中,将块提取到适当命名的方法很less会损害您的可读性。

这是你的代码,用你的标准,但是我的基本答案是你的“多less”? 没有

你没有说什么语言,但在大多数IDE中,这是一个简单的重构 – >提取方法。 有多容易,有一些参数的单个方法比2块重复代码更容易维护。

很难说抽象。 但是我自己的看法是,即使是一行重复的代码也应该被做成一个函数。 当然,我自己并不总是达到这个高标准。

干的重点是可维护性。 如果代码难以理解,则难以维护,所以如果重构会影响可读性,那么实际上可能无法满足DRY的目标。 对于less于15行的代码,我倾向于同意你的同学。

重构可能很困难,这取决于语言。 所有的语言都有其局限性,有时重复逻辑的重构版本在语言上可能比重复的代码更复杂。

当两个具有不同基类的对象在操作方式上有相似之处时,通常会出现代码LOGIC的重复。 例如,两个GUI组件都显示值,但不实现访问该值的通用接口。 重构这种types的系统要么需要采用比所需要的更通用的对象的方法,接着进行types检查和转换,否则需要重新考虑和重构类的层次结构。

这种情况是不同的,如果代码是完全重复的。 我不一定会创build一个新的接口类,如果我只打算它被使用两次,并在同一个function两次。

一般来说,没有。 无论如何不是为了可读性。 总是有一些方法可以将重复的代码重构成一种意图,揭示像书本一样的常见方法。

如果你想为了避免引入依赖而提出违反DRY的论点,那么可能会带来更多的分量,你可以得到Ayende的意见和代码,以说明这一点。

除非你的开发者实际上是Ayende,尽pipe我会坚持DRY并通过意图揭示方法来获得可读性。

BH

我接受没有重复的代码。 如果在不止一个地方使用某个东西,它将成为框架的一部分,或者至less是一个实用程序库。

最好的一行代码是一行没有写的代码。

这实际上取决于很多因素,代码使用的多less,可读性等。在这种情况下,如果只有一个代码副本,并且这种方式更容易阅读,那么也许很好。 但是如果你需要在第三个地方使用相同的代码,我会认真考虑把它重构成一个通用的函数。

可读性是代码可以具有的最重要的事情之一,我不愿意妥协。 重复的代码是一个难闻的气味,而不是一个凡人的罪恶。

这就是说,这里有一些问题。

如果这个代码应该是相同的,而不是巧合的,那么存在可维护性风险。 我会在每个地方指出对方的意见,如果它需要在第三位,我会重构它。 (我实际上有这样的代码,在两个不同的程序不共享适当的代码文件,所以每个程序中的注释指向另一个。)

你没有说过,如果这些线条是连贯的整体,你可以很容易地描述一些function。 如果他们这样做,重构他们。 这是不太可能的,因为你同意在两个地方embedded代码更具可读性。 然而,你可以寻找一个更大或更小的相似性,也可能是一个函数来简化代码。 仅仅因为十几行代码被重复,并不意味着一个函数应该由十几行代码组成。