Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am sure there's a name for this anti-pattern somewhere; however I am not familiar enough with the anti-pattern literature to know it.

Consider the following scenario:

or0 is a member function in a class. For better or worse, it's heavily dependent on class member variables. Programmer A comes along and needs functionality like or0 but rather than calling or0, Programmer A copies and renames the entire class. I'm guessing that she doesn't call or0 because, as I say, it's heavily dependent on member variables for its functionality. Or maybe she's a junior programmer and doesn't know how to call it from other code. So now we've got or0 and c0 (c for copy). I can't completely fault Programmer A for this approach--we all get under tight deadlines and we hack code to get work done.

Several programmers maintain or0 so it's now version orN. c0 is now version cN. Unfortunately most of the programmers that maintained the class containing or0 seemed to be completely unaware of c0--which is one of the strongest arguments I can think of for the wisdom of the DRY principle. And there may also have been independent maintainance of the code in c. Either way it appears that or0 and c0 were maintained independent of each other. And, joy and happiness, an error is occurring in cN that does not occur in orN.

So I have a few questions:

1.) Is there a name for this anti-pattern? I've seen this happen so often I'd find it hard to believe this is not a named anti-pattern.

2.) I can see a few alternatives:

a.) Fix orN to take a parameter that specifies the values of all the member variables it needs. Then modify cN to call orN with all of the needed parameters passed in.

b.) Try to manually port fixes from orN to cN. (Mind you I don't want to do this but it is a realistic possibility.)

c.) Recopy orN to cN--again, yuck but I list it for sake of completeness.

d.) Try to figure out where cN is broken and then repair it independently of orN.

Alternative a seems like the best fix in the long term but I doubt the customer will let me implement it. Never time or money to fix things right but always time and money to repair the same problem 40 or 50 times, right?

Can anyone suggest other approaches I may not have considered?

If you were in my place, which approach would you take? If there are other questions and answers here along these lines, please post links to them. I don't mind removing this question if it's a dupe but my searching hasn't turned up anything that addresses this question yet.


EDIT: Thanks everyone for all the thoughtful responses.

I asked about a name for the anti-pattern so I could research it further on my own. I'm surprised this particular bad coding practice doesn't seem to have a "canonical" name for it.

share|improve this question
    
"Is there a name for this anti-pattern?" The 'violating-dry' anti-pattern? :) IMHO you pretty much answered it yourself. –  Steven Jeuris Sep 12 '11 at 13:56
    
Maybe call it "The Dry Violator"? –  FrustratedWithFormsDesigner Sep 12 '11 at 14:28
2  
I call it: DRY bumping. –  AJC Sep 12 '11 at 14:54
3  
Copy and Paste coding? –  tylermac Sep 12 '11 at 17:48
add comment

5 Answers

up vote 15 down vote accepted
  1. it is just called duplicate code - I don't know of any more fancy names for this. The long term consequences are as you described, and worse.

  2. Of course, eliminating the duplication is the ideal option if only possible. It may take a lot of time (in a recent case in our legacy project, I had several methods duplicated across more than 20 subclasses in a class hierarchy, many of which had evolutionarily grown their own slight differences / extensions over the years. It took me about 1,5 years through successive unit test writing and refactoring to get rid of all duplications. Perseverance was worth it though).

    In such a case, you may still need one or more of the other options as temporary fixes, even if you decide to start moving towards eliminating the duplication. However, which of those is better depends on a lot of factors, and without more context we are just guessing.

    Lots of small improvements can make a big difference in the long run. You don't necessarily need the customer's explicit approval for these either - a little refactoring every time when you touch said class to fix a bug or implement a feature can go a long way over time. Just include some extra time for refactoring in your task estimates. It is just like standard maintenance to keep the software healthy in the long run.

share|improve this answer
3  
+1, if not only for the mentioning of duplicate code, but for the sheer effort involved in your story of code refactoring. :D –  Andreas Johansson Sep 12 '11 at 13:59
add comment

There is a reference to the WET (We Enjoy Typing) pattern but I don't know if it is a standard name.

...Software licensing is a notable exception to the DRY (Don't Repeat Yourself) practice - software licensing code should be as WET (We Enjoy Typing - the opposite of DRY) as possible.

If you isolate your licensing logic in one place, separated from other concerns, you make it far easier to modify your software to disable the licensing altogether. It is much better to repeat the licensing logic many times throughout the application, preferably such that it is executed numerous times throughout a single execution of the software.

For example, we suggest that you perform a licensing check during installation, during application startup, and whenever important features are accessed. Don't check the licence once during startup & pass that value around; instead, actually replicate the licensing check in each area. It's inconvenient, but far better than releasing a product that's easy to crack...

share|improve this answer
    
Interesting reference Fonzo. Thanks. –  Onorio Catenacci Sep 12 '11 at 17:21
2  
WET can mean: Write Everything Twice –  StuperUser Dec 13 '11 at 17:44
1  
@StuperUser I discovered that on the dailywtf yesterday... –  fonzo Dec 14 '11 at 15:31
add comment

If I understand you properly, there is too much going on in the class. That creates methods that do not follow the single responsibility principle. Leading to code that needs to be moved around, pieces taken while others left out. This could also create a lot of members.

You should also review the accessibility modifiers. Ensure those things that are public, should in fact be public. The consumer doesn't need to know about every little member...use encapsulation.

This calls for a refactor. It also appears that code is being written with no upfront design. Look into Test Driven development. Write the code how it should be called rather than calling code however it is implemented. Look into TDD for some hints on how to accomplish the task.

share|improve this answer
add comment

If you're copying code, you'll introduce a technical debt of double maintenance or more specifically: code duplication.

Usually this is fixed through refactoring. More specifically you redirect all the calls to a new function (or a new method in a new class) that has the common code. The easiest way to start is to remove all the copied code and see what breaks, in which you fix by redirecting the calls to the common code.

Getting your customer to agree to refactor code may be difficult since it is hard to convince a non-technical person to fix a technical debt. So the next time you give time estimates, just include the time it takes to refactor to your estimates. Most of the time customers do assume you're doing clean up of the code during the time you do the fix.

share|improve this answer
add comment

Sounds like spaghetti code to me. The best fix is a refactor/rewrite.

a pejorative term for source code that has a complex and tangled control structure, especially one using many GOTOs, exceptions, threads, or other "unstructured" branching constructs. It is named such because program flow is conceptually like a bowl of spaghetti, i.e. twisted and tangled...

http://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Spaghetti.jpg/175px-Spaghetti.jpg

share|improve this answer
    
-1 Refactor and rewrite are two very different options. Total rewrites, throwing software away, is never a good idea. joelonsoftware.com/articles/fog0000000069.html –  P.Brian.Mackey Sep 12 '11 at 13:49
1  
Spaghetti code is IMO a much more general - and looser - term. Although such code often contains duplcations, you can have spaghetti code without any duplication, and also highly duplicated but not spaghetti code. –  Péter Török Sep 12 '11 at 13:51
    
@P.Brian.Mackey I never said that Refactor and rewrite were the same thing. OP should decide which to use. –  Tom Squires Sep 12 '11 at 13:54
2  
I was never a fan of that article. I agree that the rewrite was a bad idea in the example cited, but just because it was a bad idea in that instance doesn't mean it's always a bad idea. For starters, will doing the rewrite block any other progress? If so, that's bad; if not, well then that's not nearly as bad. –  jhocking Sep 12 '11 at 14:25
    
@jhocking - I believe the point of no-rewrite policy is not that of blocking progress in other programs, rather loss of real fixes over time. That magical "if(goldenNugget > 22)" while poorly named, still solves a specific problem that may well be impossible to identify without hours or days of research. Now, taking that same data and improving it is what should be done instead. That is a refactor. Throwing it out and saying "we'll do it right next time" is a waste of time. The same reason resolving already solved problems is a waste of time. Adding good code on top of bad increases debt –  P.Brian.Mackey Sep 12 '11 at 18:01
show 1 more comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.