Quoting
RefactoringImprovingTheDesignOfExistingCode, p58,
- The first time you do something, you just do it.
- The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway.
-
- Or if you're like me, you don't wince just yet -- because your DuplicationRefactoringThreshold is 3 or 4.
- The third time you do something similar, you refactor.
You especially want to apply this
RuleOfThree when the first two cases aren't enough to really understand what is common and what is unique about the uses.
Also, when you have three cases, you can be fairly confident that you'll have a fourth.
Tres faciunt collegium
Note that some people take the more aggressive approach of refactoring the first time you see duplication.
OnceAndOnlyOnce! (3x)
(One such person is
RonJeffries:
http://groups.yahoo.com/group/extremeprogramming/message/31209.)
Something I said even before learning of XP was "Twice is a pattern." IE: At the point you say "oh, I've seen that [once] before," you have to go back and combine them. -- JeffGrigg
Every occurrence of similarity or differentiability has an opportunity to refactor, So RefactorMercilessly. Refactoring is not something that happens once - it happens continually. It's very inline with evolution. Nature didn't stop genetic (design) mutation (refactor) for billions of years. The practice of software development is just a few decades old. -- NitinVerma
The parallels with nature only go so far. The natural world is full of redundancies. From genomes to bird species, nature loves throwing bandwidth at the problem. Carrying the argument to its logical conclusion, it would seem that whatever code survives and propagates is the "right" solution.
The ability to distinguish between similar and identical is key here. Also, you have to tolerate a certain amount of idiomatic duplication.
Concur. Particularly if there is just enough difference in the actual work being accomplished that your
<ahem> "refactoring" makes the original procedure or whatever more effort to use, test, debug, and maintain than two separate but more easily handled pieces.
See:
ThreeStrikes,
CodeHarvesting,
ThreeStrikesAndYouAutomate,
DuplicationRefactoringThreshold