…and the ideas behind it
In this post I will share some ideas about structuring a software application. I will describe what horizontal and vertical layering for me is and show how they can be applied.
Layering an application is useful for having a better overview of the application it is clear what to expect in the specific layer. You have less complicated and non-transparent dependencies. This all applies for vertical and horizontal layers but take affect in a different way. At least you end up with a much more modular app which can be tested/unit tested more easily and is open for extension and different deployments.
In short vertical layering is about application layers inside a microservice, monolith, etc. – at least inside of single executable application. Horizontal layering is about splitting an application into different domains/services/components (e.g. microservice architecture). See the diagram below.
Layering helps a lot to get a better overview over the application. It is much easier to find things, because you know what to expect in the specific layer. And it is always clear what I can do in the specific layer (because of the contracts in the specific layer). It prevents unwanted use of code in the wrong layer. For example (in .net webapi) exposing business entities to the outer world of a web api. Or accessing the data layer directly from the controller – and so on… (When you can manipulate entities where ever you are in the program it is dangerous and you will loose the control over them and it could be come to invalid manipulations, etc.)
Furthermore you automatically avoid cycling dependencies. For example – imagine you have two application services. Each service uses a business or domain service for creating and persisting the same business entity (and do their other specific service stuff…). Because of “sharing code in business layer” or better to put that business/domain logic into it, the possibility of cycling dependency is less than using all service in one layer, because it is then not clear what to use and what not.
It is not really the thing how many layers do you have (this depends on your needs), but you should have them and only expose access through a contract to the next upper layer. In the diagram you see how this is applied.
For example in C# you can do this kind of separation in two ways. Imagine we have data, business and application layer.
You can create a project for every layer plus a contract for each one (like in the image). The data layer knows only it’s own contracts. The business layer knows from the data contract project and it’s own contract project. And the application layer knows only about business layer contract and it’s own project. With this you avoid directly accessing entities from the application layer.
You can create a project for each layer (application, business and data). And put the contracts directly in folder from that specific project. The business layer knows the data layer. And the application layer know the business layer. So to avoid direct access to the implementation we can mark the implementation classes as internal and only the contracts as final.
I like the first approach a little more because it is directly more clear and I can share the contracts as a library easily without the implementations. But both are doing there job.
Horizontal layering is for me building and using components, or sometimes libraries but above all it is separating an application into different services.
For example microservices are a good example for horizontal layers. And/or splitting an application into multiple domains. And these domains are self contained and have no need to communicate with others. Then you have multiple services which are scalable and it is clear what they are doing. Of course sometimes/often services (when using DDD in subdomains) need to communicate, but this is mostly done over messages (message broker in microservices) and or service endpoints. So there is no direct use of domain logic outside the domain from the service.
So today I would say the most important thing is to have horizontal layering to provide better possibilities to scale the application and the other mentioned stuff. But I think it is also important to have vertical layering. The more code you have in one application the more it is important to have vertical layering. For example a monolith without vertical layers is absolutely horrible to maintain and I could bet the dependencies are very confusing and it is not really clear what will be used where… If had build your monolith/big service in vertical layers, it is much more easy to create horizontal layers from it. So for me both are layering styles are important and has partly similar and sometimes other advantages then the other.
If you questions or suggestions or if you see this completely different please make a comment and we can speak about it. I am always happy to hear perspectives from other devs.