Decoupling or Coupling That Is the Question

Posted on Nov 1, 2025

introduction

Pretty much can be said regarding software architecture and trade offs and among all those things there is the so called structures we are all so used to hear about: clean architecture, onion or hexagonal architecture, etc. All of them are ways to organize the system according to how easy it is to modify/update and improve its scalability later.
Among them, one idea that is recurrent is about decoupling, which is what we are going to discuss in this post.

Clean architecture and decoupling

When we talk about architecture, clean architecture is one that I like the most, because a personal preference of mine is coding monoliths instead of microservices. This arrangement makes the program as layers (which resembles the onion architecture), each of them is independent from the level above and dependent of only the level immediately below it. As a general rule we have:

models -> repository -> services -> presentation

models is the raw database configuration, the most internal levels, repository deals with persistence and services deals with the verifications and operations, presentation is basically the external utilisation, like api calls or a cli interface… gui or tui… basically the interface that will permit the user interact with the software.
After this brief explanation we can see that each layer is responsible for one thing and they are decoupled in the sense that we can change only one of them and the others will remain mostly untouched, which is the magic of decoupling, easiness of modifications, which inspired microservices that takes it to another level of decoupling by separating logic itself in micro APIs inside a major API.

Is decoupling the magic solution and coupling really bad?

That is what I thought when I was reflecting about django, django orm, decoupling and microservices. If decoupling is really that good, what about frameworks like django that have everything integrated and dependence isn’t really a choice? Because if you need to change anything you will have a lot more of effort to do anything, so what do we get as advantage to have that? Practicality and speed! Two factors that are really important depending on the project.
The more I thought about it, the more I saw that the answer is depends and that there is nothing wrong with depending on a framework that is as reliable as django, like… no one would doubt that making a full application on rails is a bad idea nor it is with laravel.

Magic doesn’t exists but possibilities

I see those architectures as possibilities, a way to think about our applications. Some people like to decouple and make the modules as independent as possible, even if it means by exaggerating in micro services or making hundreds of directories to separate scopes. Decoupling is great when you are in an unstable environment where you don’t know if the tech stack might change or the framework isn’t batteries included and each part depends in a different external module, but when we have a complete framework like django, sometimes this trade off isn’t that bad even if it means becoming dependent of something.
What we have isn’t a silver bullet that work for everything but directions that we can take or adapt to our own reality.
Like interfaces, they are great to make a common ground of interaction, but if you exagerate they can make the code worse.

Conclusion

Decoupling or dependence isn’t inherently bad, just have a common sense and critical thinking to adapt the concepts and think outside the paradigm of your language, if possible to have a wider vision regarding a challenge, sometimes what we are preached about isn’t wrong, but depending on the situation it isn’t really convenient or the ideal solution.
Sometimes the best trade off is to complete the solution faster and with a known model, like those batteries included frameworks, without having to recreate everything with build-as-you-go frameworks that you also need to use a lot of time to think about the architecture.