Do you know the “I talk about it so often that I believe I already wrote a blog post about it” effect? It happens when you talk about something so often that you are sure to have a blog post somewhere to explain it more deeply 😉
It happens to me recently about DRY (Don’t Repeat Yourself). In a twitter conversation where I once more had to explain why DRY should not be technical. I’ve looked for my blog post about it. Just to find that it doesn’t exist yet… Thus, here it is.
According to Wikipedia, DRY is a principle of software development aimed at reducing repetition of software patterns, replacing it with abstractions or using data normalization to avoid redundancy.
One of the main arguments for avoiding redundancy is to improve software maintenance. It seems great right? If you have to modify the code in two places instead of one when you want to change a behavior, you increase the risk of error.
According to Wikipedia, coupling is a measure of how closely connected two routines or modules are.
Low coupling is often a sign of a well-structured computer system and a good design, and when combined with high cohesion, supports the general goals of high readability and maintainability.
The main issue with DRY when apply dumbly is that it
increases coupling (which is a code bad smell). Because, sharing the same code
between two things create a coupling between them. Too many developers consider
that two identic lines of code in the system must be merged and shared into
one, because we want to be DRY.
The key to have a smart refactoring in order to be DRY is to care about cohesion.
According to Wikipedia, cohesion refers to the degree to which the elements inside a module belong together. In one sense, it is a measure of the strength of relationship between the methods and data of a class and some unifying purpose or concept served by that class. In another sense, it is a measure of the strength of relationship between the class’s methods and data themselves.
If we share code between two modules with low cohesion, the result is a dramatic decrease in maintainability. We take the risk to break the second module, each time we want to change something in this shared code for the first module.
DRY Should not be technical
An easy way to avoid this pitfall is to consider the business concept of what you want to share.
If the business concept is the same for the two modules, you can share it with less risks, because it should evolve for the same reason in the two places.
If it’s just a technical concept, sharing it may be dangerous, because both modules will probably need different updates depending on their use cases.
Of course it happens because, no matter if you know/want it, you’re Domain Driven. It means that your module will evolve because of business requirements. Low cohesion means the two modules have different business purposes, then will evolve very differently. And we don’t want to share something between two things that evolve very differently.
Let me recap
- To be efficient, DRY must be combined with high cohesion (and few people remember that)
- An easy way to detect cohesion is to care about the business goal of each module
I do believe it’s one of the first good practice easy to apply that can radically change your code maintainability day after day.