Rule of Three — Three Strikes And You Refactor

Photo by Jack Hunter on Unsplash

Rule of Three — Three Strikes And You Refactor

One of the most common misunderstandings in software development is the DRY principle — Don’t repeat yourself.

It usually sounds straightforward: The DRY principle states that duplication and repetition in code that exists in two places and repeats the same knowledge and business logic should be avoided. In reality, even experienced developers never realize the difference between code duplication and knowledge duplication.

Recognizing the difference between knowledge and accidental duplication is even hard for experienced developers because a domain understanding of the code is needed.

Knowledge duplication

“Are we looking at syntax duplication or knowledge duplication?” — Anthony Sciamanna

To spot knowledge duplication basically, two questions have to be answered affirmatively:

  1. Does code exist that looks identical?

  2. Does the code repeat the same knowledge and logic?

Answering the first questions is easy. Assuming you are using a regular expression to validate password strengths:

At some other part of the application, we initialize the same variable. Obviously, code exists that looks identical.

  1. It does exist code that looks identical ✅

But, does the code repeat the same knowledge and logic? This question is the harder one. If you are unsure, you can ask a replacement question: Does changing one code block lead to changing the other?

There is true duplication, in which every change to one instance necessitates the same change to every duplicate of that instance. — Robert C. Martin

I consciously chose an easy example here. Assuming the regular expression to validate passwords is used for the same application in the same context, we would need to change the code in two places if the logic changes. That means that our application repeats the same knowledge.

2. The code repeats the same knowledge and logic

As both conditions are applicable, we can confirm knowledge duplication in the code. We can go ahead and refactor our code by removing the duplicated code.

Maybe, you already realized that answering the second question is not always easy. We need to understand the underlying business logic of the application to avoid removing accidental duplication.

Accidental duplication

To understand accidental duplication, let’s have a look at some example code:

And again, let’s check our questions:

  1. Does code exist that looks identical?

  2. Does the code repeat the same knowledge and logic?

As well as the first example, this code contains some duplicated syntax. Both, the ProductService as well as the FeedbackService are repeating this code block:

We could easily outsource this block of code to the abstract superclass CRUDService . That would save us a few lines of duplicated code.

  1. It does exist code that looks identical ✅

Now, what about the second question. Let`s start by asking the replacement question: Does changing one code block lead to changing the other?

Presuming our business logic changes:

Feedback can now be created by every user while creating products still requires having the right permissions.

This would lead us to change the FeedbackService class but the ProductService class does not need to be changed. This means that we identified accidental duplication and we should not abstract our code.

2. The code does not repeat the same knowledge and logic

“If two apparently duplicated sections of code evolve along different paths — if they change at different rates, and for different reasons — then they are not true duplicates” — Robert C. Martin

Imagine having abstracted our code by cleaning up the duplicated code, and not only our two example classes are inheriting from our superclass but many more. We would have un-refactored our code because we cleaned up accidental duplication. This is much worse than having some duplicated code.

Theoretically, we should now be able to differentiate between essential and accidental duplication.

But what if we are not sure?

Rule of Three

Three strikes and you refactor

Spotting knowledge duplication isn’t easy, and cleaning up accidental duplication is far more harmful than duplicating code.

The Rule of Three 3️⃣ defines that when you spot some duplicated code and the first two cases aren’t enough to identify shared knowledge, wait for the third duplicate before you refactor.

It’s really hard and feels terrible, but close your eyes and try it anyway. —Justin Weiss

Martin Fowler defined the Rule of Three in his book Refactoring: Improving the Design of Existing Code:

  • 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 same anyway.

  • The third time you do something similar, you refactor.

Final Thoughts

Duplicated code is one of the major reasons for technical debt and bugs in software. That`s why the DRY principle is one of the most valuable in software development. But, applying it correctly is even more critical.

Remember, whenever you spot dome duplicated code, ask yourself: “Am I looking at duplicated syntax or duplicated knowledge*?”. And if you are not sure, apply the *Rule of Three.


Thanks for reading!

Want to learn more about how I scaled my Chrome Extension to almost 100,000 users as a solopreneur? Subscribe to my stories or follow me on LinkedIn and Twitter.

If you read a lot online, make sure to check out my Chrome Extension loved by 90,000+ active user — it’s free:

Did you find this article valuable?

Support Marius Bongarts by becoming a sponsor. Any amount is appreciated!