laitimes

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

author:Flash Gene

After 2015, with the birth of a series of technical terms such as cloud native, microservices, and large middle platform, there is also a familiar term "domain driven" that has also begun to be praised on the altar. The first time I heard about domain driving was when I participated in a technology sharing meeting, and my intuitive feeling at that time was: it seems to say something, but it seems that nothing has been said, and many concepts are very "metaphysical", floating in the sky, and cannot be landed.

Ten years have passed, the middle office has passed out, and the return of microservices to monolith has become a hot topic of discussion in the technology circle. In the past one or two years of practice, the author has a deeper understanding of DDD, this article will explain some of my simple opinions, if there is a lack of understanding, I also hope that students will discuss together.

01

Domain-driven philosophy

The concept of domain drive was first proposed by Eric Evans in 2003 in his famous book "Domain Driven Design: Tackling the Complexity in the Heart of Software". It is because he has put forward a lot of abstract concepts, and we might as well put aside these concepts first, and first understand the idea of solving the problem.

1.1 Unified Language and Models

For a developer, our work is in a word: use code to implement requirements, in the process of implementation, different people, different teams, can have different practices, domain driving is one of the implementation paths. Domain-driven attempts to build a bridge between requirements and code, and the bridge is called Unified Language and Model.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

What is Unified Language? The core difficulty of software development lies in dealing with the complexity hidden in business knowledge, to deal with this complexity, first of all, we need to break the communication barriers between business and technology, in a project, not only developers, but also testing, operation and maintenance, products, PM, etc., the premise of being able to do things is to be able to explain things clearly, we know that Chinese culture is broad and profound, a sentence has completely different meanings in different environments and occasions, The idea of a unified language is to encourage constant communication within the team to ensure that a term or concept in a business domain has a unique and clear meaning.

So what is a model? I summarize it as: a kind of abstraction that simplifies the complex, abstraction is to simplify the problem, ignore the details first, think about the problem from the top, abstraction does not care about the expression of the form, but depends on how to look at the problem and analyze the angle of the problem, let's give a few examples to illustrate:

  • How many steps does it take to put an elephant in the freezer? In three steps, open the refrigerator - > put in the elephant - > close the refrigerator.

Although this is a meme, it has to be said that it is a good process-oriented abstraction.

  • Program = Data Structure + Algorithm.

This has become the most basic principle in computer science, that is, any program can be decomposed into algorithms + data structures, although the problem to be solved by the program has not been determined, but there is already a direction to think about the problem.

  • Class diagrams, flowcharts, architecture diagrams...

For a more complex system, it is difficult for us to explain it in a few sentences, at this time, drawing becomes a good way to express it, and drawing is a kind of abstraction, using different types of diagrams according to the different angles you want to abstract. For example, if someone asks you to talk about what a shopping website does, you can simplify the problem and represent it in the following diagram, that is, describe the relationship between users, merchants, and platforms, which is the idea of object-oriented modeling, and domain-driven is essentially an object-oriented modeling method.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

After the introduction of the idea of unified language and model abstraction, you can represent the process from requirements to implementation in the following figure, technical and business related students communicate and exchange requirements through unified language, describe requirements through model abstraction, and finally implement the corresponding code according to the model.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

1.2 Divide and conquer: Merge and order

Why do we talk about merge algorithms here, because the problem-solving mindset advocated by domain drive is the same as merge ranking algorithms, which can be summed up in one sentence: top-down splitting, low-up merging.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

Let's briefly review the idea of merging and sorting:

  1. Clarify the functions, inputs, and outputs of the main function;
  2. decompose the problem and determine the function, input, and output of the decomposed subfunction;
  3. Merge the return of the subfunction, and the pseudocode is as follows:
//主函数
void mergeSort(std::vector<int>& arr, int left, int right) {
   int mid = left + (right - left) / 2;


    //拆分过程 一拆二
    mergeSort(arr, left, mid); //子函数1 
    mergeSort(arr, mid + 1, right);//子函数2


    //合并过程 
    merge(arr, left, mid, right);


}
//合并函数
void merge(std::vector<int>& arr, int left, int mid, int right) {
    //实现
}           

Domain-driven still follows this idea in the implementation process: define the problem, decompose the problem, and merge the results.

Define the problem: When we are faced with a complex scenario, we first need to determine what is the problem? Where is the boundary (bounded context) of the problem, it is easy to understand the value of solving the problem, but it is easy to ignore the value of defining the problem. In the practice of the project, I don't know if you have ever encountered such a scenario: the technical students will immediately fall into the technical implementation according to the description of the product classmates, and only in the process of acceptance will they say: "Oh, it turns out that you only need to implement this requirement", which is the failure to find the core problem.

Decompose the problem: Define the problem that clarifies the boundary of the problem, we can divide the problem within the boundary, and the core idea of domain driving is divide and conquer, that is, split the sub-problems with "clear boundaries", and then solve the sub-problems. The idea of decomposing the problem here is also similar to the idea of microservice splitting (when it comes to microservices, two interesting questions are thrown here, first: domain driving is a concept that was put forward in 03, why it has not been gradually known to everyone until about 15 years; Second: what is the relationship between microservices and domain driven, I believe you have the answer in your mind after reading this article)

Merge result: It is not enough to solve the sub-problems one by one, how to string the information together is the difficulty, and there will be a coupling problem in the process of stringing, which returns to a common problem in software practice: how to achieve "high cohesion and low coupling", in fact, careful partners have found that the goal of the decomposition problem here corresponds to high cohesion, and the goal of the merging result is low coupling.

02

Those obscure terms

In the previous section, we talked about the problem that domain-driven wants to solve: reducing system complexity, and how it solves the problem: unified language, model abstraction, and divide and conquer. With these two points in mind, let's take a look at some of these abstract concepts, and I believe you will have a deeper understanding.

2.1 Doing things within boundaries: domains and subdomains

Conceptually, the field refers to the scope of engaging in a specialized activity or business, and the emphasis here is on the word scope, which is the boundary. No matter what problem we solve, the problem always has a boundary, and the clearer the boundary, the clearer the idea of solving the problem. For a complex problem, using the idea of divide and conquer, it can be further broken down into sub-problems. This kind of thinking of studying the problem has actually become commonplace, if we need to study the human body, then the human body is the object of the problem, we can divide the problem into sub-problems according to different methods, the following are two different ideas, the left figure is divided according to the "system", and the right figure is divided according to the "composition".

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

There is no so-called standard answer to how to decompose, and the way of splitting is different, in fact, it can also be said to be a difference in abstract perspective, because different abstract angles will have different research methods. For example, the study of the human body in traditional Chinese medicine will focus on the relationship between the whole and the parts, while Western medicine will focus on quantitative analysis, we can't say that it is good or bad, but the perspective of the problem is different, and the angle is abstract.

When the decomposition process is completed, we are looking for the corresponding solution ideas for the sub-problem, which is the process from the problem domain to the solution domain, and the following diagram can help you understand it more directly.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

2.2 Domains are further divided into core domains, general domains, and support domains according to functions

In the process of continuous division, the sub-domain can also be divided into core domains, general domains, and support domains according to different functions, and it should be emphasized here that the division of sub-domains is completely based on the understanding of the business, based on the business, not the technology.

  • Core domains

Different people have different understandings of competitiveness, such as taking people as an example, which one is the core competitiveness of a person, when the body is the core, people will focus on exercise and fitness; Those who believe that cognition is the core will focus on reading books and learning; People who think wealth is important will focus on their careers.... In general, it is not possible to say who is right and who is wrong, it is a different way of looking at the problem.

The same is true for companies, we look at many companies' businesses and products, which are very similar on the surface, but in fact have completely different business models, taking e-commerce platforms as an example, some core areas are logistics services and high-end quality; For a company, a core area is delineated, in fact, the direction of resource investment is determined, and good steel is used on the blade to provide differentiated value services.

  • General-purpose domains

For example, the so-called "middle platform" concept refers to the modular service of high reuse, which integrates all underlying capabilities and quickly iterates front-end functions.

  • Support domain

The supporting domain is the core domain that supports the core domain, but is not the core competitiveness of the business. This part of the business rules is relatively simple, and usually does not require an in-depth understanding of the business requirements, only the basic business needs need to be met.

2.3 Entities and Value Objects

What is an entity? There is an object with a unique identity in the business. For example, in the e-commerce scenario, an item object can be an entity, and the item has a unique identifier (item ID), and the business performance of the item may change, but the identifier is consistent throughout the business cycle, for example, an item is a commodity before purchase, and after purchase, it becomes a goods that needs to be shipped, and if it wants to be refunded, it becomes an item that needs to be recalled, but the identifier of the item will not always change.

What is a value object? For an entity object, it is not enough to have a unique identifier, it is not enough to describe the characteristics of the object, so there are attributes, for example, the attributes of a commodity generally have a name, price, picture, and place of production, while a value object is a collection of attributes of a business entity.

In practice, a business entity often corresponds to an entity class that has a unique identity, attributes, and all of its business methods. Domain-driven advocates the use of congestion model, that is, to implement all relevant business methods in the class, rather than only exposing the data directly to the outside world, which can ensure the consistency and encapsulation of business data.

//实体 
//物品类
public class Product{
    private String productId; //唯一主键 唯一标识 
    private String productName;     
    private String productUrl; 
    private String productPrice; 
    Private Address  productAddress;// 属性集合
    // get set 业务行为 ...
    public function(){}
}
//值对象 
//仓库地址类 (无主键id)
public class ProductAddress{
   private String Province;
   private String City;
   private String District;
}           

2.4 Aggregation and Aggregation Roots

When we need to complete a business function, it is often not a single person who can complete it, but everyone works together to complete the goal, in the domain driven, the entity is like each of us, the aggregation is the organization that allows us to work together, the aggregation root is the leader of the organization, so the aggregation is actually a collection of entities and value objects closely related to business logic, each aggregation has a unique aggregation root and business boundary, and the aggregation will generally be designed according to the single responsibility of the business and the principle of high cohesion, to determine which business entities and value objects it needs to include.

Let's take the shopping cart scenario as an example to experience the meaning of aggregation and aggregation root, in the shopping cart, the list of products added to the shopping cart constitutes an aggregation, and the shopping cart ID is the aggregation root, through which the outside world can access the list information, status, and total amount of purchased items.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

If we want to implement this simple scenario in code, we naturally think that we can implement the logic related to the shopping cart in a microservice, in fact, in a domain-driven, a set of related business aggregations are often implemented through a microservice. Now that we have a preliminary understanding of the related concepts of domain driving, let's sort out the relationship between them, as shown in the diagram.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

03

Split vs. merge

In the previous section, we have covered some important concepts in domain driving, and in this section we will introduce the implementation of the idea of divide and merge in domain driving, and we will discuss these two processes separately below.

3.1 Splitting and microservice architecture

Let's go back to the case of merge sorting, think about the similarities between the code we usually write and merge sorting, and we will make some simple changes to the merge sort code, as follows:

void mergeSort(std::vector<int>& arr, int left, int right) {
    //拆分过程
    //把mergeSort(arr, left, mid)改写成 
    int resA=rpc.funtionA();    
    //把mergeSort(arr, mid + 1, right)改写成 
    int resB=rpc.funtionB();    


    //合并过程 merge(arr, left, mid, right)改为
    func(resA,resB);   
}           

Think about it, isn't this the application layer code we usually write, first remotely call service A to get information, then call service B synchronously, and then combine all the result data for calculation and return, as shown in the following figure.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

Isn't this a layered architecture for microservices? The final implementation form of domain-driven is microservice, which can answer a question raised above, why the concept of domain-driven was proposed in 02, but it was not known until 15 years later, because the development of cloud native and microservice architecture is about 15 years, which provides a soil for the concept of domain-driven to survive; Conversely, domain-driven also provides the necessary methodology for the design of microservices.

Students who are clear about microservice architecture must know that one of the difficulties in microservice architecture design is the strength of splitting services, which will lead to an exponential increase in the difficulty of operation and maintenance. Comparing the domain analysis model and the microservice architecture, you will find that they actually correspond to each other, but one describes the problem from the perspective of business, and the other describes the problem from the perspective of technical implementation, which is also a combination of theory and practice.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

3.2 Merge Best Practices: Domain Events

In the process of describing the business, there is often such a description: when a certain event occurs, it will trigger subsequent events or further behavioral actions of users.

For example, after the user successfully pays for the purchase of an item, the delivery process will be triggered, and the payment and delivery here belong to different domains and have a logical order.

In view of the above events, Domain-driven advocates that the data communication mode of domain events is carried out in the form of event publishing and subscribing, and does not directly call synchronously, while the essence of event publishing is a low-coupling asynchronous data communication mode.

There are two issues to consider for synchronous calls: distributed transactions and time consumption. For transaction problems, it is generally necessary to introduce third-party components or deal with various exceptions such as timeout failures at the business layer, which can be said to be quite complex and the maintenance cost is also very high. In distributed systems, the time consumption problem will be magnified, and a request may span more than a dozen or even dozens of services, and in high-concurrency scenarios, the risk of timeouts will increase, and upstream interfaces may be dragged to death. These are all issues that need to be considered for synchronous calls.

In the scenario of domain events, a better technical choice is to use events to publish and subscribe, or take the scenario where users purchase items to pay for delivery as an example to see the implementation process:

  1. After the user places an order, the payment domain creates an event, persists the event status, publishes the event after the payment is successful, and the payment behavior ends.
  2. After receiving the user's payment success event, the delivery of the user's purchased items is triggered, and the event status is persisted and ended.
  3. The user receives a notification that the shipment is successful and waits for the receipt of the goods.
What is the significance of DDD when the middle office is outdated and microservices return to monolith?

The essence of domain events is to find the causal logic chain between domains by analyzing the user journey, and then realize the decoupling of the process through the event publishing and subscribing mechanism.

So how do we find domain events? One of the best practices is to brainstorm with project-related students under the leadership of domain experts, associate and associate all events related to the business, but the difficulty here is not how to diverge, but how to converge events after divergence, the essence of convergence is the effective classification of events, which requires people who can understand the essence of the business, so this is why there is a role in domain drive called domain experts, and this process is also represented by diagrams.

What is the significance of DDD when the middle office is outdated and microservices return to monolith?

04

summary

The above are some of my superficial views on domain-driven, if you still feel that domain-driven is a bit metaphysical after reading it, it doesn't matter, as long as you remember, whether it is technology or life, communicate more when encountering things, and decompose complex problems first.

Author: Lu Haomata

Source-WeChat Official Account: Tencent Cloud Developer

Source: https://mp.weixin.qq.com/s/izLddcVkGx94LoJmFSzR4A

Read on