Welcome to the series "Clean Code"; brought to you by "Coding Mantis"!
We all structure and organize our code into packages, though the term "package" might differ between programming languages and programmers, and we do so in order to keep similar logic together. But what is the best way to do it?
Before we answer this question, let's first take a look at our options.
There are two, virtually three, ways to package our code;
- Horizontal split (aka Layer split).
- Vertical split (aka Feature split).
- Hybrid split.
Horizontal (Layer) Split
In my professional experience, I have faced this way of splitting the code the most. The horizontal split approach focuses on grouping the logic by layer, and in web development, it's generally based on how a request travels from outside of our server down to the database and back up.
Let's now examine the pros and cons of this approach.
The pros
The horizontal split, as in the picture above, allows us to have all of our code organized in such a manner that we know where all of our controllers, services, repositories, etc. will be at any given time, which is great when our codebase is small.
The cons
On the other hand, having a bigger amount of elements per layer can cause some sort of confusion, especially when we attempt to observe what is happening in the codebase in order to make an addition, modification, or get an idea of how it works for all intents and purposes.
Vertical (Feature) Split
Encountered quite often, but not as much as the horizontal split as mentioned above, the vertical split approach focuses on grouping the logic by feature or "business unit".
If you're familiar with the microservices architecture, you've probably noticed the similarities compared to the picture above.
The pros
It allows having all related logic grouped together. This way we can have highly modular code which is much easier to navigate through, thus easier to maintain, and it also allows for decoupled logic and better scalability.
The cons
From my point of view, the only drawback to this approach is the probable need to extend a feature's functionality just to have some features communicate with each other. For example, when we need to fetch an author's details, as well as their books with their own details.
It's important to note here, however, that should this need arise it's probably an indication that we haven't separated the responsibilities of our code correctly. In this case, we could solve this by having an aggregator between the client and the server to collect the responses from two APIs and serve them in a combined fashion.
Hybrid Split
The best of both worlds. The hybrid split combines the benefits by firstly having a feature split and then a layer split inside it.
Conclusion
I find it best to split the code firstly by what it is and then by what it does. Following this approach, we can find what we're looking for in a matter of seconds, apply any changes needed, and go on about our day.
Now, besides the fact that diagrams are not my forte;
What do you think about the subject?