We often hear about how dangerous duplication is in code. “You don’t want any duplication in code, it is gonna introduces bugs” I’ve often been told, and for many years I believed that. Whenever I saw duplicate code I would extract it into a module or class. That was until I came across the book “Understanding the 4 rules of simple design”. Corey Haines, the author of this little gem, tackles the concept of naive duplication and DRY.
So what is DRY? Going back to the original definition we have…
Every piece of knowledge has one and only one representation
Corey points out that it doesn’t say anything about code. In fact, DRY has very little to do with code. Combining code that appears similar misses the point!
Sandi Metz, another software developer to follow, has also said a similar thing when she wrote on her blog about duplication.
Duplication is far cheaper than the wrong abstraction - Sandi Metz
So what example can we use to illustrate the point?
One that comes to mind is imagine we were writing a tax calculator for several countries. You came across the following:
If in South Africa and your salary is:
between 20K & 30K apply 20% tax
between 30K & 40K apply 25% tax
greater than 40K apply 30% tax
If in US and your salary is:
between 10K & 33K apply 20% tax
greater than 33K apply 27% tax
If in New Zealand and your salary is:
between 20K & 30K apply 20% tax
between 30K & 40K apply 25% tax
greater than 40K apply 30% tax
Spot the duplication?
With my old programmer hat on I would see a possibility for removing duplication. South Africa and New Zealand have identical rules! I can use a common module to calculate both! The fact is that these are not the same thing, it is coincidental that these tax rates are the same. South Africa and New Zealand are different places. If I were to collapse their rules into a single place what happens in a year or two time when one of them adjusts their tax rates - pain!
So, the next time you see duplicate code and rush to extract it first stop and work out whether it really is violating DRY or not.