让我们试着去理解为什么DRY是很重要的,然后我们就可以明白的地方打破规则是合理的:
DRY应该用来避免在两段代码在概念上做一些同样的工作的情况,所以无论何时您在一个地方更改代码,您都必须在其他地方更改代码。如果相同的逻辑在两个不同的地方,那么你必须始终记住要在两个地方改变逻辑,这很容易出错。这可以适用于任何规模。它可以是被复制的整个应用程序,也可以是单个常量值。也可能根本没有任何重复的代码,它可能只是一个重复的原则。你必须问:“如果我要在一个地方做出改变,我是否需要在其他地方做出相应的改变?”。如果答案是“是”,那么代码违反了DRY。
试想一下,你有这样的线在你的程序:
cost = price + price*0.10 // account for sales tax
在你的程序
和其他地方,你有类似的一行:
x = base_price*1.1; // account for sales tax
如果销售税的变化,你将需要改变这两条线。这里几乎没有重复代码,但事实是,如果您在一个地方进行更改,则需要在另一个地方进行更改,这会导致代码不干。更重要的是,你可能很难意识到你必须在两个地方做出改变。也许你的单元测试会抓住它,但也许不是,所以摆脱重复是很重要的。也许你会因素的营业税变成一个独立的恒定值,它可以在多个地方使用:
cost = price + price*sales_tax;
x = base_price*(1.0+sales_tax);
或可能创建一个函数来抽象甚至更多:
cost = costWithTax(price);
x = costWithTax(base_price);
无论哪种方式,这很可能是值得的麻烦。
或者,你可能有一些代码看起来非常相似,但没有违反DRY:
x = base_price * 1.1; // add 10% markup for premium service
如果你的方式来改变销售税的计算,你不会想要改变该行的代码,所以它实际上并不重复任何逻辑。
也有不得不在多个地方进行相同更改的情况。例如,您可能有这样的代码:
a0 = f(0);
a1 = f(1);
此代码在几个方面不是干的。例如,如果您要更改功能f
的名称,则必须更改两个位置。你也许可以通过创建一个小循环并将a
变成一个数组来让代码更干。但是,这种特殊的重复并不是什么大问题。首先,这两个变化非常接近,所以在不改变另一个的情况下意外改变它是不太可能的。其次,如果你使用的是编译语言,那么编译器很可能会发现问题。如果你不是编译语言,那么希望你的单元测试能够抓住它。
有很多很好的理由让你的代码干,但也有很多不好的理由。
这可能更适合程序员.se –