I have been discussing about DRY (Don't Repeat Yourself) principle also known as DIE (Duplication Is Evil) and there are votes, that any simple code repetition is always an evil. I would like to hear your opinion about the following points:
Does the above cases are good reason to give up abstraction process and just leave duplicated code in favor of risk of future changes or just readability?
DRY, which stands for 'don't repeat yourself,' is a principle of software development that aims at reducing the repetition of patterns and code duplication in favor of abstractions and avoiding redundancy.
DRY stands for Don't Repeat Yourself and the principle is that there should only ever be one copy of any important piece of information. The reason for this principle is that one copy is much easier to maintain than multiple copies; if the information needs to be changed, there is only one place to change it.
"Don't repeat yourself" (DRY) is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.
DRY BenefitsLess code is good: It saves time and effort, is easy to maintain, and also reduces the chances of bugs. One good example of the DRY principle is the helper class in enterprise libraries, in which every piece of code is unique in the libraries and helper classes.
Those are entirely valid reasons to violate DRY. I should add a third: performance. It's rarely a big deal, but it can make a difference, and abstraction can risk slowing things down.
Actually, I'll add a fourth: wasting time and potentially introducing new bugs by changing two (or more) parts of a codebase that might already be working just fine. Is it worth the cost of figuring out how to abstract these things if you don't have to and it probably won't save any or much time in the future?
Typically, duplicated code is not ideal, but there are certainly compelling reasons to allow it, probably including further reasons than what the OP and myself have suggested.
Let's try to understand why DRY is important, and then we can understand where breaking the rule is reasonable:
DRY should be used to avoid the situation where two pieces of code are conceptually doing some of the same work, so whenever you change the code in one place you have to change the code in the other place. If the same logic is in two separate places, then you have to always remember to change the logic in both places, which can be quite error prone. This can apply at any scale. It can be an entire application that is being duplicated or it can be a single constant value. There also may not be any repeated code at all, it may just be a repeated principle. You have to ask "If I were to make a change in one place, would I necessarily need to make an equivalent change somewhere else?". If the answer is "yes", then the code is violating DRY.
Imagine that you have a line like this in your program:
cost = price + price*0.10 // account for sales tax
and somewhere else in your program, you have a similar line:
x = base_price*1.1; // account for sales tax
If the sales tax changes, you are going to need to change both of those lines. There is almost no repeated code here, but the fact that if you make a change in one place it requires a change in another place is what makes the code not DRY. What's more, it may be very difficult to realize that you have to make the change in two places. Maybe your unit tests will catch it, but maybe not, so getting rid of the duplication is important. Maybe you would factor the value of the sales tax into a separate constant that can be used in multiple places:
cost = price + price*sales_tax; x = base_price*(1.0+sales_tax);
or maybe create a function to abstract it even more:
cost = costWithTax(price); x = costWithTax(base_price);
Either way, it is very likely to be worth the trouble.
Alternatively, you may have code that looks very similar but isn't violating DRY:
x = base_price * 1.1; // add 10% markup for premium service
If you were to change the way sales tax is calculated, you wouldn't want to change that line of code, so it isn't actually repeating any logic.
There are also cases where having to make the same change in multiple places is okay. For example, maybe you have code like this:
a0 = f(0); a1 = f(1);
This code isn't DRY in a few ways. For example, if you were to change the name of function f
, you would have to change two places. You could perhaps make the code more DRY by creating a small loop and turning a
into an array. However, this particular duplication isn't a big deal. First, the two changes are very close together, so accidentally changing one without changing the other is unlikely. Second, if you are in a compiled language, then the compiler will most likely catch the problem anyway. If you are not in a compiled language, then hopefully your unit tests will catch it.
There are many good reasons to make your code DRY, but there are many good reasons not to also.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With