Creating good architecture is as good as preparing a tasty meal with all the necessary ingredients. But when you need to cut those onions, do not shed tears!
Today, we will discuss Onion Architecture which is also said to be a cousin of layered and hexagonal architectures. The web world is a collection of various traditional architectures. Each of these architecture has its pros and cons.
But exactly what is Onion Architecture, on which principle it is based, what is the essence of Onion Architecture, when to implement it, etc. will be handled in this article.
Before moving ahead, you must be aware of the following design patterns:
1. Algorithm Strategy Patterns: This pattern addresses issues related to high-level strategies and explains how to exploit application characteristics on a computing platform.
2. Computational Design Patterns: This pattern addresses key computation identification-related issues.
3. Execution Patterns: This pattern supports task synchronization.
4. Implementation Strategy Patterns: This pattern addresses the issue related to the implementation of source code.
5. Structural Design Patterns: This pattern will address those issues related to the high level of applications being under development.
The key proposition of Onion Architecture is a good coupling. But then, what exactly coupling means? In simple words, it is a dependency of one thing upon another. Always, these dependencies should be inward and never outward.
Behavior Contacts: The business logic behavior is acknowledged as contracts with the use of interfaces in an object-oriented-text.
Separation of Concerns: Each layer is bonded together with the same rate of exchange.
The foundation of Onion Architecture is based on the inversion control principle. This architecture is made up of several concentric layers interfacing towards the core that denotes the domain. The unique part of Onion Architecture is – it has zero dependencies over data layers like classic multi-tier architectures. It depends on the actual domain models.
As we mentioned in the beginning that Onion Architecture is closely associated with two other architectures – layered and hexagonal. In the case of a layered approach, Onion Architecture uses the theory of layers but in a bit different way:
- Domain Model Layer: This layer is exactly at the center. It plays crucial role in defining the state and behavior of the application. Although after explaining simply, it might be hard to know what the domain layer is. For better understanding, we will consider the following example: Let us take an example of the sales order system. Now, let’s assume that there is a need to retrieve an order by order numbering. The domain will define the logic of order and order numbering. Also, the interface is defined for such behavior. Real data access implementation exists in the outer layer.
2. Domain Services Layer: This layer defines domain-specific events. We might not be in a position to define the implementation exactly, but these events are associated with the service layer which helps in defining interfaces for shipping orders, completing orders or returning orders.
3. Application Services Layer: The logic used for implementing the interfaces on the domain service layer is stored in the application services layer. This is possible only if it does not depend on infrastructure.
4. Infrastructure Layer: The outer edge of Onion Architecture is comprised of an infrastructure layer. From here, the application coordinates with the outside world.
Fig: 1 Layers when presented as circles
These layers wrapped around the previous one from Onion-like shape and depend upon solid dependency rules -outer layers depend on subordinate layers, but there is no code in the subordinate layer which can depend on any code in the outer layer.
The three inner layers, viz. domain model, domain services, and application services together make the application core. This application logic is comprised of all the necessary logic required to run and test the application as much as basic dependencies are offered at runtime. This is probably due to the dependency rule we defined in the beginning. Here, you can notice one important thing that swapping the UI or the database for the testing is possible only because, no code from the application core depends on the outer layers.
The basic principle of Onion Architecture solely depends on how the dependency inversion principle is applied with architecturally defined priorities between layers. Jeffrey Palermo, in his study clearly states the difference. According to him, the main deviation between Onion Architecture and Layered Architecture is the way of dependencies. Most people understand that in the layered architecture, almost all layers depend on the infrastructure layer. This results in bad coupling and changing the library or database provider could hamper overall business importance. Onion Architecture mainly aims at shielding your business fundamentals, and the dependency rule.
There is no standard process for implementing Onion Architecture. We have a free hand on how we want to implement the layers. You have full liberty to choose whatever level you want. That is class, module or package. Whenever dependency rules come in the picture, you have the leverage to implement the dependency inversion principle whenever an inner layer class wants to interact with outer layer class.
1. Directed Coupling: The most significant code in the application does not depend on anything. But the rest of the thing depends on it.
2. Flexibility: You have the leverage of swapping out in any of the existing outer layers and enable things to work fine.
3. Testability: You can easily and quickly test the application in isolation.
1. Learning: People tend to mix up between layers, thus spoiling the domain model.
2. Indirection: Interfaces universally.
3. Theoretically heavy: The application core is dependent free towards frameworks.
When it comes to applying Onion Architecture, it is of utmost importance to understand when to implement it. In today’s world of request and response logic, you will need a repository interface and gateways to handle the situation. This facilitates by protecting your business from undesired dependencies. On the other hand, we can see dependencies and services relied upon each other on the code level. In such cases, you will find numerous dependencies to switch with interfaces.
In brief, the Onion Architecture is applied when:
- The system is constructed around an independent application core.
- The interfaces will be defined by the inner layers. Then, the outer layers implement these interfaces.
- The inner layers can be run and separated from the infrastructure.
- Onion architecture has proven effective to lower coupling and enhancing cohesion. This overall helps to improve the performance, maintenance and testability of the system.
One of Onion Architecture is well recognized in the industry. Being powerful and closely associated with layered and hexagonal architectural styles, it has gained wide publicity. It has been observed that Onion Architecture is more suitable for C# programmers than Java programmers. However, it individually and entirely depends on whether to apply or not. Onion Architecture helps to attain maintainability objectives easily. To attain this, there is substantial workaround involved in setting up the desired structure, and also maintaining throughout the life of the system. Implementation of features might be slow as there are multiple layers involved. This is the reason why Jeffery Palermo suggests it for enterprise systems and not for smaller, complex systems.