DRY Spaghetti vs. Copy/Paste code

I have never meet a software developer that doesn’t know the DRY (Don’t Repeat Yourself) principle. It fits perfectly with the concept of code reuse that most of us learned about when we started learning how to write software. DRY is a simple principle that all the software developers I’ve worked with understands really well. We’ve all learned it to the extend where DRY code is equal to or at least part of what we consider to be good clean code. Yes, there are a lot of good things to say about DRY code.

But… yes, I’m sorry there is a but…

When you gain more experience and start working with larger systems and code bases you realize, that as in almost every other aspect of life the real world is seldom black or white, but comes in many different shades of gray. DRY comes at cost and there are tradeoffs to be made.
But why isn’t DRY code always the right thing? The short answer to that question is “Dependencies”. If you pursue a codebase that is completely DRY, you will take on more and more dependencies. If you go all in on DRY you are at high risk of developing a code base that resembles “Spaghetti code” with dependencies all over the place, where even small changes can cascade through large portions of your code.

DRY comes in shades of gray

If you have participated in architecting, building and/or maintaining a number of software solutions you will most likely have learned that code with many dependencies is not a good thing. I think it was Frank Buschmann that once said something like “Being an architect is mostly about managing dependencies”. Managing a lot of dependencies sounds like a lot of work, so what do we try to do then? Well I always try to reduce the number of dependencies in any way I can. Sometimes I even choose to break the DRY principle and copy some code into my project instead of taking a dependency on some other library. Yes, I’m admitting to it I sometimes deliberately choose to break the DRY principle in favor of keeping the number of dependencies down.

The DRY Spaghetti vs Copy/Paste scale

I sometimes consider DRY and the number of dependencies like each end of a scale. On one end of the scale you have DRY code with a ton of dependencies aka “DRY Spaghetti” and on the other end you have no dependencies and a lot of duplicated code aka “Copy/Paste”. Choosing black, white or some shade of gray on this scale is not an easy choice, because it often feels like choosing between two evils, but being conscious about the fact that you are making this choice can help you build a better solution.

Getting DRY with no spaghetti, is it possible ?

Of cause the best solution would be to break the scale so you can have both. There are a lot of great tools out there like design patterns and the SOLID principles that can help you. These tools can help you not to end up having to choose where you want to be on this scale, but they are not always enough. In fact, whenever you add a reference to an external library you are making a choice on the “DRY Spaghetti vs. Copy/Paste” scale.

What should you do ?

There is always some future cost of adding a dependency to an external library, and with tools like NuGet, NPM and the like it has become almost too easy to add dependencies. So when you are about add a reference to some external library always ask yourself the question: How can I avoid adding a reference to this library? If there is a fairly simple solution to not adding the dependency, then don’t. If it will take you a lot of time and/or money to avoid it then add it, but be aware of the future cost of managing the dependency.

Leave a Reply

Your email address will not be published. Required fields are marked *