Within this particular part, i’ll be talking about one of my favorite architecture called “Onion Architecture”. Nevertheless, allow me to recap first about what do we have so far about DDD as following:
DDD is all about how we design our software from the business perspective, not from the technical perspective. For that purpose, we must go together with the domain expert (a.k.a business expert) during the design process, thus we can keep align with the business want. The process always start with what we call as ubiquitous language (i.e. we need to have standard term to be used along with the design and implementation process). Subsequently, break the complex domain into smaller sub-domain known as bounded context and carefully define the boundaries and contract used to communicate between the individual bounded context. So each bounded context appears as a black box to another (only care about the contract interface, no need to care about the implementation details since its hidden from the outside).
Additionally, there are some pitfalls that need to be avoided during the design and implementation. Those are data centric mindset when modeling the problem domain, focusing on implementation details such as entities, repositories, etc instead of the core concepts, generic and specific technical terms, and focus on DB transactions instead of business transactions.
Ok, let’s start with the main topic now, shall we :-).
Onion Architecture was coined by Jeffrey Palermo. If you ever heard about Hexagonal Architecture (a.k.a. Port and Adapters) from Alistair Cockburn, the idea of Onion Architecture actually was inspired from this Hexagonal Architecture.
You don’t have to use Onion Architecture though you implement DDD. And you don’t forced to use DDD as well in order to apply Onion Architecture. Both are independent each other. Therefore, you are free to use other than Onion Architecture for DDD (even traditional architecture such as MVC still fit in DDD). However, Onion Architecture is a strong candidate and suited for DDD.
What make Onion Architecture different with the Traditional one ? Lets see the traditional first and come up with Onion later.
In the traditional architecture, the application’s structure is comprises of three tier/layer such as depicted below:
Traditional MVC Architecture
As we can see, on this particular architecture each layer highly depends on the layers beneath it, and every layers normally will also dependent to some common infrastructures (e.g. frameworks or utility services). With this kind of architecture, it will be difficult to give a separation of concerns because of the created coupling between each layer (each layer is coupled to the layers below it, and each layer often coupled to various infrastructure concerns). Yeah, coupling is important in order to create the interaction between components in our system, but what i’m trying to say here is that this particular architecture creates unnecessary coupling.
For instance, let’s say the team had decided to use SpringBoot to build their microservices which represent the infrastructure layer. Subsequently, after couple years the team has decided to change the framework to another or perhaps just drop the SpringBoot. With this kind of architecture, it will be difficult to deploy the new framework without any adjustment (changes) in the other layers since each layer is highly coupled to the framework (infrastructure) layer. Thus, there will be a possibility for the team in breaking the current business layer which contains all of the business logic (business domain). Bear in mind that, a good system should have criteria MECE (Mutually Exclusive Comprehensively Exhaustive) a.k.a. “loosely coupled, highly cohesive”. Therefore, the more coupling you created in your system, there will be more effort you need to change the system and breaking it to small independent parts.
On the other side, the biggest offender (and most common) is the coupling of UI and business logic to the data access. Transitive dependencies are still dependencies. The UI won’t work if the business logic isn’t there, same as the business logic won’t work if the data access isn’t there. Data access changes frequently, and whenever the data access changed, you will also need to adjust / change the business layer with this particular architecture. And, did i mention before ? Changing the business layer which contains the business rule will have a big risk for the company, especially when the business already stable and the current system has widely used by the users in the Company.
Here’s why Onion Architecture come to the rescue :-). Take a look at the diagram below for the Onion Architecture.
There are lot aspects of Onion Architecture, but the main goal is how it controls the coupling. The basic rule that you need to bear in your mind is all coupling is toward the center. For instance in the depicted diagram we can say as follow:
- The “Infrastructure” layer will know about the “Application Services”, “Domain Services”, and “Domain Model”.
- The “Application Services” will know about the “Domain Services” and “Domain Model”.
- The “Domain Services” only know about the “Domain Model”.
- The “Domain Model” only know about itself.
- The inner layer will not and should not know about the outer layer. Hence, the “Domain Model” doesn’t know about “Domain Services”, “Application Services”, and “Infrastructure” layer. Same as the “Domain Services” doesn’t know about the “Application Services” and “Infrastructure” layer, and so forth.
In the very center, we see the “Domain Model” which represents the state and behavior of the model for the Organization/Company (i.e. the application we’re trying to build). Around the domain model are other layers with more behavior where the number of the layers can be vary (i.e. no restriction of the number of the layers).
“Application Core” will glue all the layers like “Domain Model”, “Domain Services”, and “Application Services” (again, the numbers of the layers can be vary which means we can have more layers rather than just those 3 layers).
“Domain Model” is the very center, and since all coupling is toward the center, then the “Domain Model” must be coupled only to itself as mentioned before. Typically, the “Domain Model” consists collection of interfaces called Repository Interfaces those provide saving and retrieving mechanism for objects in the system. Thus, i can say that the “Domain Model” defines the contract of the object’s system behavior especially for saving and retrieving mechanisms. Remember, only the interfaces (not the implementation). We can leave the implementation later on different layers (i.e. the infrastructure layer).
The outer layer (i.e. “Infrastructure” layer) is reserved for things that frequently changed. These things should be isolated from the “Application Core”. UI, Automation Test, DatabaseAccess, NetworkAccess, FileAccess belongs to this “Infrastructure” layer.
So, how does this “Onion Architecture” related to “DDD” ? We will see later once we get to the implementation. Just “stay tuned” :-).
Any comments or suggests would be well appreciated.