The application of DDD in the evolution of public comment trading system

original
05/10 10:23
Reading amount 1.5W

This article collates from the 73rd issue of Meituan Technology Salon, Architecture Evolution and Practice Based on Domain Driven Design (DDD). It mainly introduces the core concepts and common design ideas of DDD, and introduces the evolution process of the public comment trading system in combination with DDD. Finally, it makes some summary and thinking. I hope these contents can be helpful or enlightening to everyone.

1 Introduction to VW Dianping Trading

This article mainly involves three types of transaction business scenarios, including overseas travel, group purchase in shopping malls and content commercialization. In the public comment app, there are food, shopping, shopping malls, scenic spots, tickets, local play and other channel entrances in overseas city stations, where you can purchase overseas travel trading products. In the domestic shopping/mall channels, you can find shopping mall group purchase discounts and shopping mall group purchase vouchers.

In addition, if the merchants have promotion needs, they can purchase creative services from the "Dianxing" entrance of the merchant side app (Kaidianbao App), and the notes delivered by the ultimate talent will be displayed in the review app information flow. Specifically, overseas travel products cover scenic spot tickets, restaurant reservations and leisure entertainment; The group purchase products of the mall include ordinary group purchase orders and second kill group purchase orders, which are applicable to the preferential activities of the mall; Content commercialization products allow businesses to purchase images and texts or video notes of experts to promote their own services or products.

2 Overview of domain driven design

2.1 What is domain driven design

Domain driven design is a software design method, which is mainly used to deal with complex business requirements. We can divide it into three parts: "domain", "drive" and "design". "Field" refers to specific business scope or problem domain, such as e-commerce, medical care, insurance, etc. After identifying the domain, we can identify the core business issues. For example, in e-commerce, the core issues may involve commodities, inventory, warehousing and logistics; In the insurance field, it may focus on insurance, underwriting and claims settlement.

"Design" in DDD usually refers to the design of the domain model. DDD emphasizes that the domain model is the core of the system, which reflects business concepts and business rules. "Drive" has two meanings: first, the business problem domain drives the process of domain modeling; The second is the process of domain model driven technology implementation or code development. Ensuring the accuracy of the domain model is the key, because it can ensure that the code implementation can truly reflect and solve the core problems of the business.

Domain driven design is a design idea that deals with highly complex domains. It controls the complexity of business by separating the complexity of technical implementation and building a domain model around business concepts to solve problems such as software difficulty in understanding and evolution. Domain driven design is a design idea. It first embodies the idea of separation, which separates the business complexity from the technical complexity. Secondly, it embodies the idea of divide and conquer. It divides and conquer through the domain model, bounding context or sub domain.

2.2 Core concepts of domain driven design

Domain driven design involves many core concepts. We will focus on "unified language" and "bounded context". The "unified language" runs through the whole process of domain driven design, from strategic design to tactical design to the final code implementation. It is very important for demand analysis, knowledge extraction and the final code implementation.

"Bounding context" is a bridge connecting problem space and solution space. On the one hand, when we analyze problems in problem space, it is the boundary of language and model; On the other hand, in the solution space, we determine the application boundary and technology boundary through the context of the boundary, so as to help us determine the solution of the whole system and each boundary context.

2.3 Process of domain driven design

First, domain driven design requires the joint participation of business, product, R&D and QA. It should be based on the understanding of the problem domain and business vision, and should be fully discussed to reach a unified understanding. In this process, domain knowledge should be refined and a unified language established. At the same time, it further refines the domain knowledge, decomposes the problem domain into core sub domain, support sub domain and general sub domain, designs the domain model through the model driven design idea, connects the business and system through the domain model, and there will be new cognitive iteration in the model driven design process. These cognitive iterations further enrich the unified language, so domain knowledge is a process of continuous iteration and spiral advancement.

3 Evolution of public comment trading system

The development process of comment trading system has three stages from the business perspective and the technical perspective. From a business perspective:

  • The first stage is the stage of single business line and single business form. In this stage, we only support the business scenario of overseas travel transaction, including the business form of booking;
  • The second stage is the stage of single business line and multiple business forms, and the business forms become more abundant;
  • The third stage is the stage of multi business lines and multi business forms.

From a technical perspective, it has mainly experienced three stages of evolution, including simple architecture, microservice architecture and platform architecture.

3.1 Simple architecture stage

This stage was the initial stage of our business and system. At that time, we only supported one or two categories of transactions in the form of reservation, which was relatively simple on the whole. At the same time, our team was also small at that time. In order to quickly support the continuous exploration and trial and error in the process of business from 0 to 1, Our main idea in technical system construction is to make some simple divisions of business function modules according to business links, so as to achieve rapid iteration and delivery.

At this stage, our system architecture is also relatively simple, and we split the foundation according to the business. Specifically, the access layer is divided into merchant B end, commodity C end and order C end, while the service layer is divided into merchant, commodity and order three parts. The traditional MVC hierarchical architecture is adopted as a whole. This kind of architecture did show its advantages in the early stage of the project, namely "simple" and "fast".

However, with the increasing and complex business requirements, the system began to expose some problems, which can be summarized into two aspects:

First of all, we adopt a data-driven design. Usually, we set up database tables first, which makes the model unable to intuitively reflect the actual business situation. Secondly, because of the traditional hierarchical architecture, we map database tables to persistent objects (PO), and then conduct procedural programming through CRUD operations in the service layer. When there are similar but different requirements in multiple scenarios, it often leads to repeated writing of similar code, which ultimately results in logical dispersion and insufficient cohesion of the system as a whole.

Taking the order refund logic as an example, we are faced with a variety of scenarios, including refund before/after order confirmation, payment before/after performance, and refund initiated by different roles such as users (buyers), merchants (sellers), customer service, and the system. Although the refund business logic initiated by these different scenarios and roles is similar to a large extent, there are also some differences between them.

Under the traditional MVC architecture mode, due to the lack of in-depth understanding and precipitation of the business field, calls between services often lack a clear structure, leading to logic intertwined. In addition, the R&D team may not pay enough attention to the design principles of high cohesion and low coupling in the system iteration process. Therefore, there are often multiple duplicate and similar order refund code logic within the system, which not only reduces the readability of the system, but also brings challenges to the maintainability of the system.  

3.2 Micro service stage

With the increase of business categories and diversification of business models, our business and system complexity has risen rapidly, and the team size has also expanded accordingly. This complexity is mainly caused by three factors:

First, the expansion of business scale has brought about the increase of system scale and code volume; Secondly, the accumulation of business requirements leads to duplicate code, complex dependencies within the system, and various technical components and parallel and asynchronous solutions introduced to meet the requirements of high availability and performance; Finally, frequent changes in business requirements also increase the complexity of the system.

To meet these challenges, our main idea is to manage the software scale through divide and conquer, optimize the system structure by using the principles of system layering and separation of concerns, and deal with frequent demand iterations by isolating changes. These strategies are core concepts of domain driven design (DDD). Based on this, we have implemented the separation of microservice architecture to better manage and control system complexity.

In terms of the implementation method of domain driven design, we refer to the content of industry practice and combine our own understanding, we divide the implementation process of DDD into the following four stages:

  1. Understand the problem domain : The core of this stage is to deeply analyze the business value, requirements and build a business conceptual model. Produce unified language and sub domain division to ensure that the team reaches consensus on business understanding.
  2. Identify the boundary context : In this stage, we determine the boundary context through the boundaries of organization, business and application, and clarify the relationship and interaction between different contexts.
  3. Domain modeling : Including domain analysis, design modeling, and continuous iteration of models. The goal of this phase is to build a model that reflects the core business concepts and rules.
  4. Model implementation : The implementation phase mainly depends on the application hierarchical architecture, microservice architecture and application integration to ensure that the domain model can be effectively implemented in the system.

Understand the problem domain

Business value analysis helps to assess the complexity of the system, and can guide us to identify the most critical business areas. Business requirements analysis is a key knowledge extraction process, which involves a variety of methods and tools, such as event storm, four-color modeling and use case analysis. We use a relatively lightweight use case analysis method.

Before use case analysis, we first need to conduct a detailed analysis of the business process. This step helps us find and identify specific business use cases by disassembling business processes and links. The analysis of transaction business processes is simplified here, because most people are familiar with e-commerce business processes. For unfamiliar business fields, we will need to conduct more in-depth business process and scenario analysis.

We divide the transaction business process into four main parts: customer cooperation process, merchant order process, online transaction process and capital settlement process. With the decomposition of these processes, we can enter the specific use case analysis phase.

In the use case analysis phase, we take the merchant order loading process and online transaction process as examples to illustrate. The main roles involved in the business order process include business and operation. Merchants are responsible for creating new commodities, putting commodities on the shelves, removing commodities from the shelves, and updating commodity inventories. The operation personnel participate in commodity review, including key use cases such as review passing, review rejection, and review list viewing. As for online transaction process, its participants are mainly buyers, merchants and customer service. Buyers' behaviors include purchasing goods, paying, applying for refund and viewing orders, while merchants deal with key use cases such as order confirmation, sending vouchers, write off vouchers and order retrieval. Customer service is involved in after-sales service, involving order refund, order compensation and other core use cases.

After completing the business process and use case analysis, we can preliminarily classify the problems according to the relevance, divide them into different sub domains, and establish a unified language. In order to better refine knowledge and provide necessary information for identifying boundary context and building domain model, we need to deeply analyze each use case and formulate use case specification to extract key concepts.

In practice, we did not strictly formulate the use case specification, but used the description in the product requirements document. In the technical scheme design phase, we will also use methods similar to sequence diagrams and interface descriptions to elaborate use cases. No matter which description method is used, the key is to adhere to the use of a unified language, which is crucial for extracting core concepts from the description. This will not only help the communication between team members, but also facilitate the subsequent design and development work.  

After business process analysis, use case analysis and the formulation and writing of use case specification, we have a full understanding of the domain knowledge of transaction business, and built the corresponding conceptual model. In this model, the seller is responsible for the creation of the goods. The user selects the goods to place an order. During the purchase process, the discount may be used. After the order is completed, financial intervention is required to settle the business.

After classifying these key concepts, we identified several sub domains, such as merchants, goods, orders, discounts and settlements. A question may arise here: Is it really necessary to divide sub domains through such a complex analysis and refining process for the fields we are already familiar with? In fact, for experienced architects, it is indeed possible to quickly complete the identification and division of sub domains, which also shows an artistry in the process of domain driven design. However, these systematic analysis steps ensure that even team members who are unfamiliar with the field can accurately understand the business and make appropriate architectural decisions.

In the problem domain analysis phase, the main output includes two parts: one is the unified language, and the other is the sub domain division.

  1. In terms of unified language, we refined the unified language of merchants, buyers, commodities, etc. through use case analysis, and enriched the unified language through the collation of use case specifications, including sales rules, sales units, order items, etc. We can use these unified languages for communication and later model design and code implementation.
  2. In terms of sub domain division, we finally identified such sub domains as shown in the figure. In combination with the core value of providing one-stop service experience for users and an integrated sales platform for merchants that we obtained in the value analysis phase, we focused on the commodity domain and order domain as core domains.

In addition, sub domains can be divided by business and organization perspectives. From the business perspective, they can be divided by business links or business directions. What we use is to divide by business links. We divide the whole business process from merchant cooperation to commodity ordering to transaction and settlement, Determine sub domains according to each link divided.

When the target system provides customers with products in multiple business directions, sub fields can be divided according to business directions. For example, the banking system can be divided from several directions, such as savings, wealth management, foreign exchange, etc; When the target system is used for enterprise management, it can be divided by business functional departments from an organizational perspective.

Identify the boundary context

After a full analysis of the problem domain, we enter the stage of bounded context recognition. I mentioned the importance of the clearance context, which is an important bridge between the problem space and the solution space. On the one hand, when we analyze problems in the problem space, it is the boundary of the language and the boundary of the model, that is, the boundary of the business. On the other hand, in the solution space, we determine the application boundary through the context of the boundary.

Therefore, when we identify the boundary context, we mainly focus on the business boundary and application boundary. First, we classify the business activities listed in the problem domain analysis phase based on semantic relevance and functional relevance, give priority to functional relevance, and get a preliminary boundary context division. In the analysis process of our trading system, this result is basically consistent with the sub domain division result.

What is the granularity of the boundary context? It has a certain relationship with our business complexity, technical complexity and team size. In combination with our actual situation, we further identify and divide the boundary context of the two core domains of goods and orders.

After careful consideration, we found that although goods and orders are core concepts throughout the entire business process, different participants and concerns are involved in different stages of the business process, and the demands on system capabilities are also different.

Taking commodities as an example, it involves the creation, approval and release of commodities, as well as the display and sales of clients. In the stage of commodity creation, merchants pay attention to the efficiency of recording and the management of commodity production process; In the audit phase, the operation pays attention to audit demand and audit efficiency; In the display sales phase, users focus on commodity information, price inventory and how to make purchase decisions. The situation of orders is similar, and the focus is different in the purchase, performance and after-sales stages. Therefore, we have subdivided the boundary context of goods and orders to ensure that the system design can more accurately meet the business needs of each stage.

Although the process of identifying the boundary context is still a process of splitting and solving the problem domain in essence, it is also the boundary of application and technology, so we also need to consider some quality requirements and technical factors, but it should be noted that we still follow the principle of business before technology, and when considering technical factors, It is still necessary to ensure the integrity and consistency of the domain model.

We further divide the boundary context from three aspects: quality attribute, service integration and function reuse. Taking commodity computing as an example, commodity computing is heavy, with many tasks and complex rules. In order to avoid affecting the normal display and sales of commodities, we have disassembled from the display context. In addition, our goods and orders involve interfacing with many third-party systems. In this context, the integration of third-party services is divided into separate direct context, so as to isolate the changes brought about by the differences of third-party systems on internal goods and order related systems. In terms of function reuse, we consider refining the functions involved in multiple boundary contexts as a separate context, such as the merchant permission context.

The boundary context encapsulates the business capability based on vertical segmentation. How can multiple boundary contexts cooperate to complete a complete business scenario? This involves the mapping of the boundary context. According to the communication integration mode and the team collaboration mode, there are multiple mapping relationships. Among them, we use anti-corrosion coating Open host services and publishing languages are linked to isolate upstream and downstream changes and maintain the stability of the entire domain model.

Domain modeling

In the domain modeling phase, we can generally divide it into domain analysis modeling and domain design modeling. First of all, it mainly analyzes use cases, use case specifications and user stories in detail, from which we can find domain concepts through noun and verb methods to build our domain analysis model. On this basis, we identify the entities and value objects in these concepts based on the metamodel of DDD tactical design, and design aggregation according to the invariance of business rules.

Taking orders as an example, here is our simplified model, including orders, payment orders, performance orders, vouchers, and refund orders. When the status changes, the aggregations collaborate through domain events.

Model implementation

After the identification of the boundary context and the design of the domain model are completed, the next step is the code implementation phase. How can we map specific business processes or business activities to our system for code implementation. Here we first conduct hierarchical and structural disassembly of business processes and activities from the business perspective. In fact, our previous use case analysis and use case specification are this disassembly process. After disassembly, we map them to the implementation of user interfaces, application services, domain services, aggregations and ports according to certain mapping relationships.

Finally, we divide microservices according to the context of the boundary, and implement the internal services according to the hierarchical architecture. On the whole, it is divided into access layer, application layer, domain layer and infrastructure layer based on the separation of concerns and SOLID principle. Finally, it is necessary to maintain the stability of the domain layer. The access layer and the application layer isolate changes from the top, and the infrastructure layer isolates data and differences and changes in external dependencies from the bottom by means of dependency inversion.

3.3 Platform stage

With the continuous development of business, more transaction business scenarios have emerged, such as shopping malls group buying and content commercialization. Technically, the underlying system capabilities can be reused to improve the support efficiency of each business through the idea of platform. At the same time, DDD's strategic model also focuses on how to better manage large business systems in the organization. Therefore, we can combine DDD to build a platform domain model and business expansion model, so as to complete the platform transformation more efficiently.

We mainly take the overseas transaction business with the most complex business as the main domain model, and map and match the domain model obtained by disassembling the group purchase and commercial business of the shopping mall with the main domain model according to the DDD domain modeling process. After the identification, consolidation and reorganization of the same category items, we get the platform domain model and the expansion model of each business. In our actual implementation process, in order to achieve the goal of maximizing the reuse between multiple businesses, we further refined the construction of the platform domain model, and disassembled the platform domain model into the basic domain model, as well as the booking business model, group purchase business model and other domain models divided by business form.

In addition, in order to improve the cooperation efficiency between the business BP and the platform team, based on the division of the platform domain model and the business domain model, we have adopted the plug-in based integrated development model. Through the definition of extension points, each business line implements business customization based on the business extension model in its own plug-in package, integrates the platform domain model and business extension model, and finally realizes the complete business process and business scenario.

4 Summary and reflection

DDD is an open ideology, whose core is to guide the whole design process through the establishment of domain models.

  • First, this paper believes that strategic design may be more important than tactical design, because it covers the understanding and organization of business processes and core concepts.
  • Second, domain modeling is a dynamic and iterative process, rather than a static waterfall process. This process is similar to a modeling vortex, which iterates from strategic design to tactical design. In the process of tactical design, if some aspects are found to be unreasonable, it is necessary to adjust the strategic design. Similarly, the division of subdomains and the identification of bounding contexts are also dynamic and need to be continuously optimized according to new discoveries.
  • Third, DDD does not force the adoption of specific architecture patterns. It focuses on whether the complexity of business and technology has been effectively separated. Whether it is a clean architecture, a hexagon architecture or a traditional DDD hierarchical architecture, as long as this goal can be achieved, they are all feasible choices. Even if MVC hierarchical architecture is adopted, it is also applicable as long as business and technical complexity can be separated.

Finally, let's briefly highlight the thinking models of engineers, which are also crucial in the implementation of domain driven design (DDD). On the one hand, engineers need to cultivate user thinking, business thinking and product thinking, which is conducive to in-depth understanding of business and problem domains. Based on this understanding, engineers can use structured thinking to decompose problems and abstract thinking to refine models. On the other hand, engineers can effectively translate design into actual code implementation by combining layering, divide and conquer and engineering thinking.

5 References

  • [1] Deconstructing Domain Driven Design -- Zhang Yi
  • [2] Domain Driven Design - How to Deal with the Core Complexity of Software - Eric Evans
  • [3] Domain Driven Design Patterns, Principles and Practices -- Scott Millett, Nick Tune
  • [4]《Business Model Generation》-- Alexander Osterwalder

| In the Meituan official number menu bar dialog box, reply to keywords such as [2023], [2022], [2021], [2020], [2019], [2018], and [2017] to view the Meituan technical team's collection of technical articles over the years.

| This article is produced by Meituan technical team, and the copyright belongs to Meituan. You are welcome to reprint or use the content of this article for non-commercial purposes such as sharing and exchange. Please note that "the content is reprinted from the Meituan technical team". Without permission, this article may not be reproduced or used commercially. Please send an email to tech@meituan.com Apply for authorization.

Expand to read the full text
Loading
Click to join the discussion 🔥 (1) Post and join the discussion 🔥
one comment
thirty-five Collection
zero fabulous
 Back to top
Top