Layered architecture
In application system development, it is ok to adopt a strict, single, truly layered architecture, but in reality we have used multiple architectural patterns to design systems. When you have multiple paradigms of architecture mixed together, don’t you get the phenomenon of “calling a deer a horse”?
Strictly hierarchical architecture
When studying layered architectures, layered architectures are often described or explained through conceptual definitions or OSI seven-tier applications (architectures) :
The architectural pattern Layers helps divide the application into groups of subtasks, each at a specific abstraction layer.
Image from POSA, Vol.I, P22
As an applicator who introduces layered architecture into a project, we should implement layered architecture from a more specific specification:
- There must be unidirectional coupling between adjacent layers. The upper can only depend on the lower, and the lower can never depend on the upper.
- There must be one-way communication between adjacent layers. The upper layer calls the interface provided by the lower layer, and the lower layer can never call the upper interface.
POSA, Vol.I gave us more implementation specifications, but I had to deal with the one-way dependencies of the layers. This is because some people have some confusion about the partitioning (subordination) of certain objects when using hierarchical architecture, especially when introducing hierarchical architecture into a project’s directory structure.
If you are interested in learning more about the implementation specification of layered architecture, please refer to POSA, Vol.I, pp. 26 to 29.
Relaxed Layered Systems
Domain-driven design (DDD) uses a loosely layered architecture with less rigid relationships between layers. Each layer may use the services of all the layers below it, not just the services of the next layer. Each layer can be translucent, meaning that some services are visible only to the previous layer, while others are visible to all layers above.
Note: The loosely layered architecture is still a one-way dependency, meaning that the upper layer can only call the lower layer’s services, and the lower layer cannot call the upper layer’s services.
Layering Through Inheritance
At the same time, domain-driven design (DDD) also adopts inheritance hierarchy architecture, the high-level inheritance and implementation of low-level interfaces. We need to reorder the layers and move the infrastructure layer to the top.
Note: Inheritance hierarchies are still one-way dependencies, which means that the domain, application, and presentation layers cannot rely on the infrastructure layer, but the infrastructure layer can rely on them.
Domain layer UserRepository interface:
package com.mallfoundry.user.domain;
public interface UserRepository {
User save(User user);
}
Copy the code
Infrastructure layer JpaUserRepository implementation class:
package com.mallfoundry.user.infrastructure.persistence;
public class JpaUserRepository implements UserRepository {
private final EntityManager entityManager;
public JpaUserRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public User save(User user) {
return this.entityManager.merge(user); }}Copy the code
Packages versus layered architecture
We do use packages to classify hierarchies, but package names don’t really represent hierarchies.
Repository
We typically place the repository implementation in the infrastructure layer because of our inheritance hierarchy. If you are using a loosely layered architecture, you need to place the repository implementation at the domain level. This is due to the layer’s one-way dependency principle, which you should not break. There is no reason to break the one-way dependency principle of a layered architecture unless you don’t use a layered architecture.
A three – or four-tier architecture
We should study (analyze) hierarchical architecture from chaos to order in this historical process, especially when we are in the environment of front and back end separation, what kind of partition changes the application system faces when using hierarchical architecture.
-
Phase 1: The application system has only two layers: the presentation layer and the database layer. In the view, you can directly use the access interface provided by the database to operate data, such as JDBC. In the view, you can directly use the ResultSet to represent data. (A special note: Use the ResultSet directly in the view.)
-
The second stage: the application system is divided into three layers: presentation layer, domain layer and database layer. At this stage, we are already aware of the model, which means that instead of using a ResultSet directly in our view, we use structs or object classes from the programming language that the ResultSet maps to. This means that conceptual structures in business domains can be abstracted from representations in programming languages.
-
The third stage: the application system is divided into four layers: presentation layer, application (business) logic layer, domain layer and database layer. Since the business logic still exists in the view, we need to separate the business logic in the view from the view, which is where the application layer comes in. There has also been some progress in the presentation layer, which uses the MVC architecture. By calling the interface provided by the application layer in the Controller and obtaining the model data returned by the interface, and combining the Model and view in the Controller, the rendering work is finally completed. It is the use of the MVC architecture at the presentation layer that allows the view to be loosely coupled to the lower layer.
Application systems using layered architectures are basically mature in the third stage. Since we are talking about the layered architecture of domain-driven design (DDD), we still need to make further additions. Specifically, it includes two supplements:
-
The fourth stage: object oriented development and application, this stage on the overall level of division without big changes. The specific changes are related to the application layer and domain layer content, more specifically, the domain layer changes. The appearance of object orientation makes people start to use object oriented to design domain model. This means that the object model represented by properties and operations is used to abstract the conceptual model in the business domain. This also means that the business logic in the application (business) logic layer will also be taken over by the object domain model, and the application layer only needs to control and coordinate the logic related to the object domain model. Fortunately, Eric’s systematic elaboration of this phenomenon in more detail led to the book Domain-Driven Design.
-
The fifth stage: the impact of the separation of the front and back ends on the layered architecture. In a back-end separation project, the presentation layer is completely separated from the back-end, which only needs to provide interface data, such as RESTful, gRPC, Thrift, and GraphQL. Is the back end still a four-tier architecture? This really comes along with two paths: one is the back-end model (BFF) that serves the front end. The other is an interface pattern based on aggregate objects. The difference is that the BFF changes frequently, and the latter does not change because the front end changes frequently.
Open source electricity
Mallfoundry is a fully open source multi-merchant e-commerce platform developed using Spring Boot. It can be embedded in existing Java programs or run as a service in a server, cluster, or cloud.
- Domain model adopts domain driven design (DDD), interface and object oriented design.
Project address: gitee.com/mallfoundry…
- It feels good. You can give it a star.