You’ve probably heard the names of architectures like DDD, CQRS, or Microservice many times at work, in interviews, and so on. They’ve basically become the trend these days.
But are these architectures really that good?
Does the three-layer architecture still have a place in the area of clean code, or is it just too basic and trivial?
For many of us, the first architecture we get to know in the area of clean code is the three-layer architecture. Then little by little we come across fancier and more professional-looking names like CQRS or DDD, or on a larger scale of the whole system architecture, microservice.
All of these architectures, along with the benefits they bring, also come with problems. I want to point out some of these issues.
Problems of DDD
Identifying Aggregates: Identifying aggregates correctly is often not as simple as you might think. Right now, the market is full of “nice-looking” code that follows all the rules, while because of incorrect identification of boundaries and aggregates, the code not only has much worse performance than it could, but also a large portion of it needs rewriting and review. Code that was written due to mistakes in analysis and understanding of the system.
Data Loading: The next issue is data loading. Since we know an aggregate is loaded along with all its relations, many companies (not all though) after some time, when their database grows, realize the problem. While during development everything seemed fine. Then they sit down to find a solution for the problem they themselves created, and who knows what comes out at the end (though some of them do find correct and good solutions).
Problems of CQRS
Hard Debugging: Debugging and tracing it is only easy for the person who wrote the code.
And God help you on the day when inside one handler another handler is also called and so on… you forget where you started from.
Parallel Development: Another issue I’ve seen a lot. A developer writes a handler (whether command or query doesn’t matter) and then leaves the team. When another developer joins the project and is asked to implement something similar, I can guarantee with 90% probability he will write it from scratch. Because he can’t find the existing handler to modify it (doesn’t even know it exists), and even if he finds it, since he doesn’t know where else it’s being used, he prefers to create a new one to be on the safe side.
Problems of Microservice
High Technical Complexity: This is one of those choices that can easily ruin a simple and good project if not used in the right place. It brings along a tsunami of tools and technical complexity concepts, a lot of extra coding, and if you don’t have enough experienced human resources, development becomes extremely slow.
Risk of Wrong Choice: Many times, halfway through the project you realize it wasn’t worth it at all, and every day the project progress gets slower and slower. Splitting services and implementing the communication between them drains the beauty out of the project.
So with all these issues, why are they still so popular?
Of course, alongside these problems (which are my personal opinions, by the way) they also have many advantages that you already know, so I won’t repeat them. But personally, I don’t recommend them for starting a project (if it’s version 1, not a rewrite of an existing project or something like that) because they impose a lot of code and rewrites on you during development.
The three-layer architecture is simple, practical, clean, organized, easy to refactor, and even to transform into other architectures. I highly recommend it. If you’re unsure about using other architectures but want to write clean code, go with this one at the start.
Conclusion (personal opinion)
I can confidently say an architecture is valuable only when it helps you focus more on the business—delivering what the customer needs—instead of having so many technical complexities that the customer’s requirements end up at the bottom of the list.
All those architectures are good, but not to start your project with. The further you go, the more you’ll get caught up in technical complexities rather than the business. And because of insufficient understanding of the whole problem space, you will definitely be forced to refactor many times.
But if you’re starting a project where you already have full (or at least good enough) knowledge of the business, then it can be the right choice.