Why should DDD architecture prefer hexagonal architecture? | JD Cloud technical team

1. Traditional layered architecture

An important principle of the layered architecture is that each layer can only be coupled with the layer below it.

There are two types of layered architecture: one is a strict layered architecture, which stipulates that a layer can only be coupled with the layer directly below it; the other is a loose layered architecture, which allows any upper layer to be coupled with any lower layer.

The figure below is a typical DDD traditional layered architecture.

Each layer in the above layered architecture has its own responsibilities:

The user interface layer is responsible for processing user requests and user display;

The application layer implements use cases or business processes in different business scenarios. Among them, the application service usually receives the request from the user interface layer, then obtains the aggregation instance through the resource library, and finally executes the corresponding command operation, as shown in the following example:

// 应用层的用例 
public void cancelOrder(Long orderId) { 
    Order order = orderRepository.findById(orderId); 
    // 领域层的业务逻辑 
    order.cancel() 
    orderRepository.save(order); 
}

The domain layer implements the core business logic of the system, mainly including the domain model generated based on DDD business modeling. The business logic here is different from the business process in the application layer, as shown in the above code example;

The infrastructure layer provides common technologies and basic services for other layers, such as data persistence.

2. Problems with traditional layered architecture

The resource library (Repository) in DDD is used to obtain or persist aggregates, and each aggregate has a corresponding resource library. It can be seen that the resource library should be located at the same layer as the aggregation, the resource library interface definition should be located at the domain layer, and the resource library interface implementation needs to rely on the persistence mechanism of the infrastructure layer. layer architecture is a problem.

If the implementation of the resource library interface is placed on the infrastructure layer, the infrastructure layer will depend upwards on the domain layer, which violates the principle of layered architecture: each layer can only be coupled with the layer below it.

Or it can be placed in the domain layer, but this will make the domain layer dependent on the implementation details of data persistence, causing the domain layer to no longer be a stable layer.

It can also be placed on the application layer, but it will have the same problem as placing it on the domain layer.

Is there a better way?

Yes, use dependency inversion to break the principle of layered architecture.

3. Dependency Inversion Principle

The Dependency Inversion Principle (DIP), proposed by Uncle Bob, is defined as follows:

High-level modules should not depend on low-level modules, both should depend on abstractions. Abstractions should not depend on details, details should depend on abstractions.

We put the implementation of the resource library interface on the infrastructure layer, so that the infrastructure layer depends upwards on the domain layer. Although this violates the principle of layered architecture, it conforms to the principle of dependency inversion: the domain layer (high-level modules) does not depend on the infrastructure layer (low-level modules), and both depend on the resource library interface (abstraction) . After adopting dependency inversion, adjust the location of the infrastructure layer at the same time. At this time, the layered architecture is as follows:

4. Hexagonal Architecture

After the layered architecture adopts the dependency inversion principle, the concept of layering does not actually exist. Whether it is high-level or low-level, it only depends on abstraction, as if the entire layered architecture has been flattened. The flattened layered architecture is as follows:


Adding the symmetrical half on the left side to the flattened layered architecture, the result is similar to a hexagonal architecture, as shown in the figure below.

The hexagonal architecture is also called ports and adapters. In this architecture, there are corresponding adapters for different interaction methods of system input and output, such as http, rpc, mq, data persistence, etc., and the adapters interact with the internal through the application layer API.

The hexagonal architecture allows applications to be driven by users, programs, automated tests, and batch scripts in a consistent manner, and it makes application boundaries clearer. For more information about the hexagonal architecture, you can view the original translation of the hexagonal architecture

5. Why not choose a clean architecture?

Clean architecture is an architectural design concept proposed by Uncle Bob in his book "The Way of Clean Architecture" after summarizing and abstracting the hexagonal architecture and other similar architectures.

The book concludes that the hexagonal architecture and other systems designed with similar architectures have the same characteristics:

Framework independent: The architecture of these systems does not depend on a function in a feature-rich framework. Frameworks can be used as tools, but there is no need to adapt the system to the framework.

Can be tested: The business logic of these systems can be tested independently of UI, databases, Web services, and other external elements.

Independent of UI: The UI of these systems can be easily changed without modifying other parts of the system.

Independent of database: We can easily replace Oracle and SQL Server used by these systems with databases such as Mongo, BigTable, and CouchDB. Because the decoupling between business logic and database has been completed.

Independence from any external agency: The business logic of these systems does not need to be aware of the existence of any other external interfaces.

Combining the design concepts of all the above architectures, Uncle Bob proposed a neat architecture design concept, as shown in the figure below.

 

The concentric circles in the above figure represent different levels of the software system, and usually the closer to the center, the higher the level of the software.

The clean architecture specifies the dependency rules between layers: the inner layer (higher layer) does not depend on the outer layer (lower layer), and the dependency relationship between the layers of the hexagonal architecture also follows this rule.

So far, it can be considered that the clean architecture is a guiding ideology of architecture design, and the hexagonal architecture is a specific architecture design of the clean architecture.

6. Summary

The layered architecture and hexagonal architecture after adopting the dependency inversion principle are actually in line with the clean architecture design concept. But the use of ports and adapters in the hexagonal architecture allows applications to be driven by users, programs, automated tests, and batch scripts in a consistent manner, and at the same time makes application boundaries clearer, thereby better preventing domain layer and application layer logic leaked to outer layers.

7. Reference

  1. "Implementing Domain Driven Design"
  2. "Clean Architecture"

Author: JD Retail Jia Wenxiong

Source: JD Cloud Developer Community

 

RustDesk 1.2: Using Flutter to rewrite the desktop version, supporting Wayland's alleged GPT-4 model architecture leak: Contains 1.8 trillion parameters, using a mixed expert model (MoE) Musk announced the establishment of xAI company deepin V23 successfully adapted WSL CentOS project claims " Open to all" Rust 1.71.0 Stable Release React Is it having an Angular.js moment? Microsoft launches a new default font, Aptos, to replace CalibriMicrosoft : Increase efforts to use Rust IntelliJ IDEA 2023.1.4 release on Windows 11
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/10089180