DEV Community

Rafal Stozek
Rafal Stozek

Posted on • Updated on

Please do repeat yourself (DRY is dead)

First of all, let me apologize for the clickbait-y title, but we need to talk about Don’t Repeat Yourself (DRY) principle.

Story 1

Few years ago we were asked to help with further development of an existing platform in the blockchain industry. It was a product directed to traders and helped them automate tax fillings. And it was the biggest copy&paste-based project I have seen in my life.

It was written in PHP. If you know PHP then you know that each .php file acts as an entry point to your code - and from there you usually import (include) utilities, libraries which are common to your project. That is if you don’t use a framework. This one didn’t.

This project was created from the ground up by its founder who learned programming while creating and maintaining this product.

They didn’t have much programming knowledge beforehand and didn’t know all of these good practices and fancy rules that we have. So each .php file was a copy of a previous one with modifications needed for given route/view. Tons of repeated code.

And here’s what’s really important: at this point the product already made millions of dollars.

Let that sink in. No amount of copied code, repetition and what we would call “bad quality code” stopped the product from being successful.

What’s more is that we were able to pretty quickly identify repeated code and introduce the right abstractions because we already knew different use cases from the duplicated code.

But please be aware that I'm not advocating this kind of development. It's an EXTREME example showing that you don't need to be a perfectionist.

Story 2

I’ve known developers who lived to not repeat themselves. I think that at some point they went from “in general it’s better not to have too much repetition” to “if you repeat any code then you will burn in hell”. This is one of these stories.

We were working in a company which had multiple related products. And something that one of the developers did blew my mind. They were working on a new application and decided that they could use a two-line function from the previous project (3 line if you count the function’s definition).

The choice here was simple - just copy these 3 lines of code into the new project. But as a lot of developers think - including this one - “repetition is root of all software evil”. So they spend two days setting up a common library (including deployment process etc) just so they won’t duplicate 3 lines of code.

Now ask yourself how does that benefit the project and how it gets us closer to delivering on our objectives.

The source of all evil

By simply googling “Don’t repeat yourself” I learned that:

  • Repetition is the root of all software evil
  • Duplication is waste
  • If you do it then you don’t understand how to apply abstractions
  • It decreases quality of code
  • It should all be eliminated

It does sound like bad idea, right? But at this point it sounds like we vilify it. It sounds like if you do it then you are a bad developer! Like there isn’t any scenario where you should do it. But ya’ll use StackOverflow, don’t you?

Did you at any time ask yourself a simple question - is it really THAT bad that I copy and paste a little bit of code? Does it have any benefits?

Only a Sith deals in absolutes

Here’s the thing - every rule in software development makes sense at most 80% of the time. Each was coined in some specific context - for which it made sense. But that context got lost in translation and some people began to follow the rule religiously instead of treating it as a rule of thumb.

This is our fault. We make those principles sound so absolute. Don’t repeat yourself means don’t repeat yourself. Then it’s passed from one person to another, copied over blogs, books over and over until it becomes the truth and all context and all the nuance is lost.

So here’s an alternative that I think some of you should try:

Try not to repeat yourself too much. But sometimes you can. Because sometimes it may make sense.

It’s not as catchy phrase though.

Please repeat yourself

This rant is already getting too lengthy for my taste, so let’s get to the point. There are numerous cases where repeating yourself is not only not an anti-pattern but it’s actually a tool.

I love repeating myself. Especially when I’m writing tests. I copy tests all over the place and change what’s needed for the given test. This results in a lot of duplication. When I’m done I simply go through these tests and see what’s the best way to reduce (not completely eliminate) repetition and what can be extracted into separate abstractions.

I could spend a lot of time upfront to figure out how do I want to set up the tests, what helpers do I need, then redoing everything because it turns out that 2 of 25 tests need a little bit different setup. But why would I do this if I can just see where the code takes me? Why not see what’s actually needed instead of doing all this guesswork?

This is not just for tests, but tests are where this is most obvious and I would encourage you to start there.

The overuse of DRY (Don’t Repeat Yourself) is an anti-pattern in itself. Overzealous duplication removal leads to bad abstractions because developer is creating imaginary abstractions instead of uncovering real ones.

Repeating yourself is basically giving yourself the time and space to come up with the right abstractions instead of engaging in guesswork and clairvoyance. We don’t know what the future code will be. We don’t understand all the use cases at first or ways in which our code will be used. If we introduce abstractions too soon then in best case we end up rewriting everything.

Repeating yourself is a great tool to uncover abstractions.

What other people say

As you may guessed I’m not the first person to notice this. There are two great articles about this topic:

You should definitely read them as they extend this article nicely and will give you more understanding on when to use duplication. Here’s a few excerpts:

“duplication is far cheaper than the wrong abstraction”

”prefer duplication over the wrong abstraction”

— Sandi Metz, “The Wrong Abstraction”

“Avoid Hasty Abstractions”

”Optimize for change first”

the big takeaway about AHA Programming is that you shouldn't be dogmatic about when you start writing abstractions but instead write the abstraction when it feels right and don't be afraid to duplicate code until you get there.”

— Kent C. Dodds, “AHA Programming”

Conclusion

I want to be clear that I’m not inviting you to make a mess. I am pointing out that some level of temporary duplication is healthy. First story is supposed to show you that despite what you may think - the success of a product does not depend on that but instead it depends on business development.

So copy code and modify it when necessary to give yourself space so you can uncover real abstractions instead of imaginary ones. Of course - that’s not the only method to uncover better abstractions. Talking to stakeholders and understanding business better is another way that we will discuss in the future. But it’s not a situation where you need to pick one over the other but rather complementary methods.

There is a lot of rules of thumb in software development - or “good practices”. Usually they work when you understand context and apply them sensibly. Sadly there is a lot of dogma in software industry, it’s driven by hype and emotions and rarely by pragmatism. So remember that these “good practices” are not “all or nothing” but more of a “try to do this more than the other thing and you’ll be good”.

Latest comments (64)

Collapse
 
gerhardengelbrecht profile image
steffyG

I want to add to this, although I agree that over-abstracting code can be bad. You should not think that in the coding world there is something like temp code. That becomes the practice in the company you work at. I do believe in design sessions, the example of what you use for DRY, only shows that although the developer went to route for creating a lib, that is the potential problem he didn't plan anything, he didn't go to his team with a design document, problem statement. He just jumped making a huge decision, leading to a waste of time. DRY was not the problem here, planning was, don't just jump into coding

Collapse
 
nadimattari profile image
Nadim Attari • Edited

Unfortunately you haven't understood the meaning of DRY principle. DRY is NEVER dead!

DRY principle means "Do not repeat YOUR BUSINESS LOGICS"

Copying some/part of a package/library is ALWAYS OK (e.g. not to include a whole big package/library when you'll be using 5% of it; in this case you can copy only part of what you need, tailor it according to your business logics et voila!)

If you fail to apply the DRY principle in your business-logics (services), then the mess you'll be creating will produce technical debt, maintenance issues and much more!

[Edited]

I am a PHP developer, but do some Golang also. One of the Go proverbs is "A little copying is better than a little dependency." go-proverbs.github.io/

Collapse
 
cemmanzy profile image
cemmanzy

please i need mentor on html. am a newbie in coding. i ust need someone to mentor me....

Collapse
 
ucvdesh profile image
Daniel Silva

So, you like to work twice and make the development process slower to avoid thinking? I know that you don't have to overthink everything, but it's a basic thing to think before coding to avoid make a bulky and heavy project.

Collapse
 
janezk7 profile image
janezk7

"Repeating yourself is basically giving yourself the time and space to come up with the right abstractions"
Well put. Good read

Collapse
 
yahyaerturan profile image
Yahya Erturan • Edited

Over-engineering is a killer. Agreed, however if you are developing some library, some component or similar, abstraction definitely makes you think better and it results with a better output mostly. Yet, I believe first code it, make it work, use it in real life projects to understand possible use cases. Then make it better with refactoring, abstraction, etc. For my experience, it is mostly more obtainable goal.

Collapse
 
nmuta profile image
Nmuta Jones

I scoffed when I first read the title of this article but right now as we speak, I'm writing some production code where I'm realizing that if I go too far in DRYing up a certain pattern, it will actually make it so abstract that it will be difficult for other devs coming after me to quickly understand what's going on.

I agree that you can write WET code, let it cook for a while, and then DRY up whatever needs to be optimized instead of immediately drying up everything from the start as a dogmatic practice ( which is what I tend to do ). There is some merit in this article, as infuriating as the title may be.

Collapse
 
qorbani profile image
Reza Qorbani

You need to apply more than one principle if you want to be successful! Engineer

Ignoring DRY is not a solution AT ALL! One of my top principles that I use alongside DRY is YAGNI (You Ain’t Gonna Need It) which means if you don’t need to build common library to enforce DRY, then you should not do it!! That simple!

Don’t try to use these Principles in silos and try to build a practice of applying top principles alongside each other.

My best combination is (In order of priority):

  • YAGNI
  • KISS
  • SOC
  • DRY
Collapse
 
frandev profile image
Franco

I agree, in my personal case, in the past i was fall into imaginary abstractions only because i was not want to repeat some little pice of code, by a little amoung of time. This imaginary anstractions were a headache since then.

From my experience, it is quite better first code, and then, refactor that code identifying the actual abstractions

Collapse
 
brainwipe profile image
Rob Lang

In my opinion, YAGNI, DRY, WET, SOLID, CUPID, GoF are all tools to be applied appropriately and I agree that vilifying it is a problem. In face to face conversations with developers of some experience, we know this to be true.

The root of that problem is clickbait titled articles. Like this one. 90% of junior devs (who we are appealing to in the articles), will read the title, share it and move on.

Your article is good. If the title wasn't so utterly terrible, I'd share it with the team. Please don't clickbait in future.

 
webjose profile image
José Pablo Ramírez Vargas

Thanks for the piece of data. I really cannot care any less since I'm not a US citizen.

Thread Thread
 
pawelzaicwttech profile image
Paweł Zaic

Your ego is so high, that you better watch out to not fall from it - you may hurt yourself ;]

Thread Thread
 
webjose profile image
José Pablo Ramírez Vargas

Yeah, that only applies to things that are volatile. My "ego" as you say, is "flying high" based on rock-solid knowledge acquirement. Unless I have a stroke or something, I'll remain "high". But thanks for worrying! 😏 And welcome to my fan base. It is amazing how people try to bring you down. As I have told others, hate demonstrations just tell me how higher I am from the average crowd.

Finally, you may want to read more than one message in a thread. Cheers, fan.

Collapse
 
noverkill profile image
noverkill • Edited

Can't agree more. 20 years ago I worked at a company where we used a kind of template code base to develop web portals. This base code was copy pasted every time a new page with new functionality is needed and we just made the necessary modifications, and as the base was very generic, usually very little modification were needed. We just had to make the modification that was specific to that new page / functionality the rest remained basically the same damn duplicated code. And our life was nice and easy... I have never seen a more productive way of doing development ever since. Also it was very easy to understand / modify / debug the code base which was actually in 80 % percent duplicated code. But how beautiful and generic was that duplicated code, that you could see everywhere in the application. The way that it got so generic by time, is that we always improved this generic part of the code as we worked on more and more projects, so by time it just got more and more perfect.
This kind of code base full of duplicated, generic code, needless to say is very very easy to understand, follow as you basically have the same things going on everywhere with very little alteration.Also there is so many tool you can use to modify code with repeating pattern in bulk. (e.g. sed etc..) So it is not a problem at all, but the opposite. It is very very easy to do... Of course after improving these generic code base for years, it would have been also easy to refactor and remove the duplicity. But actually if you have enough experience and you can imagine how easy is to work this way, or you have even worked with generic code templates before, you can easily understand that removing the duplicity and try to reuse the code in any other way would have just made the development more problematic, more complicated and complex. So there was no point to do that.

On the other hand If I have a look to code written with frameworks like Laravel, Symphony etc. which are popular nowadays, they are much much much worse to work with in every respect.... Much harder to understand, follow, debug, modify, learn... IMHO today with all of these over-engineered over-hyped engineering patterns and principles people just make their own life basically a living hell.They do not even have an idea that coding can be done in a much simpler way. They just follow the mainstream. Nobody wants to understand that over-complicating things, targeting complexity with more complexity are not a smart thing at all, but right the opposite! It is like people just try to show how can somebody create an incredibly over-complicated obscure solution for even the simplest problem. E,g, targeting a simple problem using these framework is a huge over kill for starting. It is like they just want to make sure nobody can understand how stuff work and then they think they are smart when nobody can understand the obscurity they create. It is kind of like a stupid mind game for people who feel like they are mentally superior. They think over-complicating things will make them look smarter. Nothing can be farther from the truth. I have also seen many very successful projects generating million of dollars in revenue used by millions of people with a code base so simple contradicting every currently popular over-complicated over-hyped principles and patterns. Lacking actually all of that. To be honest all really successful applications are like that. They target complexity with simplicity and not the opposite or any other way. The real genius is when somebody solving the complex problem with simplicity. The problem that you need to solve can be complex and complicated but not your solution. The solution for a complex problem must be not more complicated and complex than it is needed as a minimum. The problem is that people mix this up and think if they can solve simple problems in a complex way then they can also do the opposite. It can be further from the truth. I also have to say that after 20+ years in development I have seen many many different code base. I have seen many duplicated code. The problem is not the duplication itself. It all depends what kind of code gets duplicated. The problem is when horrible code gets duplicated, and this is what happens most of the time and this is why code duplication has a bad reputation. But again it is not the duplication itself theproblem... When good quality code gets duplicated with a good reason, then it is actually very good thing and does not necessarily need any changing.
The stupidity is to blame the duplication itself instead of the horrible code that gets duplicated.
If you think about this is how these stupid principles get built by idiots.
Like "code duplication" is the root if the evil LOL
If you think about it, it is actually scary how many stupid "engineer" are there in this industry to make it possible to these baseless "principles" to raise to existence.

Collapse
 
youdev profile image
Younes

BTW, the AHA programming link is broken

Collapse
 
ayoubmehd profile image
Ayoub

I think "please repeat yourself" fall in to:

  • building the right abstraction require time that the product need for something else
  • for test, I think that test need to be simple, because how can you make sure that tests are working? Am I wrong?
Collapse
 
yihao profile image
Yihao • Edited

Here is a piece of video in which Rob Pike, one of the creators of Go, explained the principle of "a little copying is better than a little dependency". He showed this with an example from the Go standard library where they made the deliberate decision to copy and paste a piece of code in order not to introduce unnecessary dependencies. (Sorry Rob, because of this you will never be nominated a MS MVP)