The Strange Relationship between Duplication and Coupling

This short post hopefully contains no new knowledge for you. Its mere intention is to make you contemplate an interesting relationship between coupling and duplication for a while.

Duplication is Bad!

As professional programmers, true software craftsmen, the clean coders, [insert your title here], we’re often taught that duplication is bad and should be avoided at all cost. We even have (at least) two widely known principles related to this problem, namely, “Don’t Repeat Yourself” and “Once And Only Once“.

The idea behind these principles is obvious – if some piece of information/behavior is represented in two separate places, we have to update both when our understanding changes. If it’s in five places, we have to update all five, and so on. As we all know, this is both annoying and error prone. How the hell am I supposed to track all such places in a codebase with thousands or millions of lines of code?

And so we, professional programmers, eliminate duplication mercilessly whenever we see it.

But So is Coupling!

The principle is often taken to the extreme where every piece of code that looks like some other piece of code has to be eliminated. A prime example of this being all the systems where the same class is used to model the domain, to be a REST request, to be saved in the database, and sometimes even more. Well, why would I create 3 classes that look exactly the same, just to, later on, map between the three?

Heck, I even copy-pasted the class when writing this small example! That’s an obvious violation! Kill it!

The thing is, you should actually consider that kind of design. Really carefully. And, as you probably figured out already, you could do that for the sake of decoupling.

Whenever you add a new field to the Employee class, you have to update all three. That’s the obvious downside of duplication. What many people fail to see, is that this kind of “update”, does not have to be exactly the same in all three cases. Let’s consider a simple evolution of the Employee class:

This paymentStrategy could be different kinds of payment methods, or different payment intervals, or whatever alike. Anyway, it’s a classical strategy example. How would the two other classes evolve now?

Obviously, we are not going to serialize the strategy as-is. We need some enum or a String, that will appropriately represent the kind of strategy. If we were to use the same class for serializing purposes, our mind will keep suggesting that we drop the pattern altogether and do it some other way.

Now, there are “workaround patterns” like an enum-based strategy, but does that really make your code simpler? Let’s consider the two snippets:

It’s like… how much time did you save? How much better is the code below than the one above?

And that’s not everything. If the paymentStrategy is required to add an employee, and you’re using the Employee class as a request, you just changed your API contract in a breaking way! How nice of you, huh?

There’s more!

Let’s say that you’re given a requirement to add some information about the organizational hierarchy to the system and display that as a nice “tree”. Simple change, we just need the immediate manager and we can go from there.

The tree does the job and everybody’s happy. As a next step, they ask you to add department information to the few. Another simple change to the Employee class!

I hope that there’s a big, red light shining in your head now. We’re filling our simple payroll system with irrelevant information! What’s more, we’re tying the payroll stuff with the organizational stuff by making them use the same Employee class all over the place. That’s bad coupling, again!

In such a case, if you were to think about a possible solution, you might easily end up with this:

That’s… dddd… duplication! Wooops!


As I said, I hope that nothing here was new to you. At the same time, I find this relationship between coupling and duplication something important enough to mention here. If you were having a hard time justifying to yourself the use of patterns like DTO, or architectural styles such as Clean Architecture, now you have at least two extra arguments. Unless you accept some data duplication here and there, you’re dragging yourself into problems like “I can’t update my domain class, because it will break some contract” or “every single thing in my system depends on this class”. Don’t go there.

About the Author Grzegorz Ziemoński

King of Tidy Java, nerd that thinks about producing perfect software all the time and proud owner of 2 cats.

follow me on:
  • Konrad Jamrozik

    According to domain-driven design the duplication is fine as long as it doesn’t happen within the same bounded context. If the REST request and database access are in the same bounded context you should have only one interface representing the concept of Employee. You can achieve this by using “SQL-speaking” decorators to add db access, and probably you could handle the REST request in conceptually similar way: