Should we duplicate code?
-
I have always had the view that duplication is bad. There are always exceptions, but most of the time I it seems bad to me. Unit tests are one are where I tolerate it more but in production code it's something that I rarely find desirable. Some people duplicate things two or three times and only eliminate the duplication on the third or fourth time. I really can't understand why somebody would blindly follow this rule. I understand the argument that we may not know how to refactor something if there are aren't enough instances of the duplication but I find that it is rarely the case. At least if you don't know how best to refactor something then keep it simple. The rule seems crazy as why would you do something if you know it's bad? Eliminating duplication is usually quick and, in my opinion, usually makes things much easier to read, particularly when you have half as much code to read/understand. As an example, imagine we want to format a number as a currency. We could have the following
x.ToString ("£0.##")
Having it once seems fine, but not really more than once. Surely, as a very simple refactor, something like the following would be better?
Format.AsCurrency(x)
Surely the time saved by the readability would outweigh the code of writing it and it solves the problems of duplication. Deliberately duplicating code doesn't make much sense to me, but maybe I've been working with people who have taken things a bit too far?
-
I have always had the view that duplication is bad. There are always exceptions, but most of the time I it seems bad to me. Unit tests are one are where I tolerate it more but in production code it's something that I rarely find desirable. Some people duplicate things two or three times and only eliminate the duplication on the third or fourth time. I really can't understand why somebody would blindly follow this rule. I understand the argument that we may not know how to refactor something if there are aren't enough instances of the duplication but I find that it is rarely the case. At least if you don't know how best to refactor something then keep it simple. The rule seems crazy as why would you do something if you know it's bad? Eliminating duplication is usually quick and, in my opinion, usually makes things much easier to read, particularly when you have half as much code to read/understand. As an example, imagine we want to format a number as a currency. We could have the following
x.ToString ("£0.##")
Having it once seems fine, but not really more than once. Surely, as a very simple refactor, something like the following would be better?
Format.AsCurrency(x)
Surely the time saved by the readability would outweigh the code of writing it and it solves the problems of duplication. Deliberately duplicating code doesn't make much sense to me, but maybe I've been working with people who have taken things a bit too far?
The principle of Do not Repeat Yourself (DRY) is one of those areas that is taken too far by some code zealots. Let's take your ToString example here, you notice after a couple of times that you have the same ToString code so you decide to introduce an AsCurrency method. That seems straightforward enough, but you're working in a large codebase so you don't notice that the same logic has been added in pieces of the code that you don't visit. Worse still, somebody has done this elsewhere:
Then there was that piece of code which looks like this.
public class FormatConstants
{
public const string GBP = "£0.##"l
// .... other patterns removed for brevity
}...
return myItem.ToString(FormatConstants.GBP);
...What we're seeing here is that others have attempted to avoid repeating code with varying degrees of success. In all of these cases, there is an element of repeated code because differnt people have taken different approaches to to avoid repeating code. Even if the code doesn't look exactly the same, you are repeating the intent of the code. Now you have introduced yet another way to represent this same conversion. In six months time, someone else comes along and has to add a currency ToString in a few places so they refactor their code to avoid adding repeated code. If you're lucky, they have looked through the codebase looking for other places that does the conversion and picks an already written one; if they've searched using ToString("£0.##") then they might not have found the match so they end up adding yet another new way of formatting this one item. What has happened here is that the search to remove duplication has ended up creating a mess - and this is just with a simple example.
The bottom line is, DRY is a great principle and one that you should try to stick to if it makes sense but you have to accept that, in some cases, you aren't going to achieve it and you shouldn't beat yourself up over it.
-
I have always had the view that duplication is bad. There are always exceptions, but most of the time I it seems bad to me. Unit tests are one are where I tolerate it more but in production code it's something that I rarely find desirable. Some people duplicate things two or three times and only eliminate the duplication on the third or fourth time. I really can't understand why somebody would blindly follow this rule. I understand the argument that we may not know how to refactor something if there are aren't enough instances of the duplication but I find that it is rarely the case. At least if you don't know how best to refactor something then keep it simple. The rule seems crazy as why would you do something if you know it's bad? Eliminating duplication is usually quick and, in my opinion, usually makes things much easier to read, particularly when you have half as much code to read/understand. As an example, imagine we want to format a number as a currency. We could have the following
x.ToString ("£0.##")
Having it once seems fine, but not really more than once. Surely, as a very simple refactor, something like the following would be better?
Format.AsCurrency(x)
Surely the time saved by the readability would outweigh the code of writing it and it solves the problems of duplication. Deliberately duplicating code doesn't make much sense to me, but maybe I've been working with people who have taken things a bit too far?
Contrast duplicating, inlining and premature optimizing. Or the fact the "pattern" may not yet have fully materialized in the mind. It's not the first time one has pulled together "similar" code only to realize you just dug a deep pit because you didn't consider the full impact. Which is very easy in the "agile" environment where they pump out bits of code in ignorance of the big picture. As for the ToSTring() example, I use xxxAsSomething() ... which inevitably winds up including xxxAsSomethingDifferent(), etc. I've now established a pattern that creates functions out of everything ... even "one-timers". And then programming becomes a real drag.
It was only in wine that he laid down no limit for himself, but he did not allow himself to be confused by it. ― Confucian Analects: Rules of Confucius about his food