Small teams can also do DDD-Part 1

About the author: Hu Zhengjun, head of the Yujiahui architecture team, located in Changsha, Hunan. Development, operation and maintenance, testing, and big data are all responsible, but not sophisticated. Be willing to refactor complex systems and embrace DDD

The previous article said that a small team can also be a middle station. It mentioned that we use the domain-driven design (DDD) methodology to develop the middle station. This article will share why we use DDD, and the next article will talk about how we Practice DDD.

 

DDD appeared very early. In 2004, Eric Evans wrote "Domain Driven Design: The Way to Deal with the Complexity of the Core of Software", but it is not widely used. In Changsha, there are very few companies using it.

In recent years, DDD has become popular with microservices. In various technology groups, DDD is not consistent with each other. There are also some online training and book publications. For example, PICC's architect Ou Chuangxin opened a column at Geek Time A book will be published this month. However, although everyone talks a lot, there is less.

I think the reasons are:

<1> The system is not complicated and there is no need to use DDD; 

<2> DDD has many concepts, it is difficult to understand, too lazy to learn; 

<3> Even if one person learns it, it’s useless. It needs to be used by the team. Due to the lazy nature of human nature, DDD has a high requirement for business and development, so I don’t want to do it. CRUD is better.

 

DDD is a set of methodology to solve the construction of complex business systems. There are two major parts: strategic design and tactical design.

The core of strategic design is unified language and bounded context, and the core of tactical design is independent domain logic layer.

Why do complex business systems use DDD can be explained from three dimensions.

These three dimensions are software development process , complex system design , and module coding .

It can be seen that these three dimensions are one-level and one-level reductions. The software development process involves multiple positions (product manager, development, testing, business operation and maintenance), which belong to the dimension of development process, and the position involved in complex system design is architecture Teacher or senior development belongs to the dimension of architecture design, and the positions involved in module coding are mainly development, which belongs to the dimension of code writing. Let's first analyze what are the problems in these three dimensions, and then see what guidance DDD can provide.

1. Software development process 

The development of a simple system does not need to be divided into so many positions. Some part-time small projects that were done during the university are all requirements, development, testing, and operation and maintenance by one person. The efficiency is very high. If there are many people in multiple positions It is very inefficient to do it.

However, this situation is different as the complexity of the project increases. One person cannot handle everything. So we set up various positions and let professional people do professional things through the division of labor.

Taking the development position as an example, it is divided into front-end and back-end development, and because of the requirements of technical complexity, labor must be divided. One theory is that the establishment of knowledge barriers and effective exchange can improve efficiency. For a detailed discussion of this aspect, you can watch the video of Bacha. The improvement of efficiency through professional division of labor is reflected in many places in life, such as assembly line operations. This is also mentioned in the Wealth of Nations and Scientific Management. For detailed discussion on this aspect, you can see the video of Bacha.

 

Here comes the first conclusion:

Technical knowledge in the software development process improves efficiency through division of labor to establish knowledge barriers

However, there is another type of knowledge in software development that cannot be solved by division of labor. The arrow in the above figure indicates that domain knowledge must be passed along with the post. Requirements analysts convert business into requirements documents, and then the business knowledge in the requirements documents must be passed to the development , Development must be understood clearly before you can work. In reality, there are many situations like this. The development requirements are not fully understood, so I start designing and coding, and finally make things that are different from actual business requirements. Rework, development and product managers There are many contradictions. How to quickly transfer business knowledge is an urgent problem to be solved.

 

Here comes the second conclusion:

Business knowledge in the software development process needs to eliminate knowledge barriers to improve efficiency

 

From the two conclusions, there seems to be a conflict. From the first conclusion, the division of labor is meaningful, and from the second conclusion, it is better not to divide the labor. With the improvement of the professionalism of various positions, the division of labor is inevitable, so how to solve the problem of business knowledge transfer, a core model of DDD is a unified language to solve the problem of solving business knowledge transfer.

The unified language has two meanings.

1. Unified communication language . We have determined the meaning of business terms in advance, and we have unified cognition in all positions of business and technology, so that when we communicate, since the understanding of business terms is already at the same frequency, it will save a lot of communication costs.

Here is an example where there is no unified language. Our company has a concept of a channel. Every time we discuss this channel, everyone understands it differently. Some use an e-commerce platform as a store, and some use an e-commerce platform. When a channel, some people understand it as other meanings. This is because every company has some historical reasons to change the definition of nouns.

2. Unified domain model and code model . We know that the most important knowledge accumulation of a system is code and documentation. Of course, many companies have no documentation. Programmers are all pissed and hate others for not writing documentation and hate writing documentation by themselves. Think about it when a newcomer takes over a project. This project has a design document and code. The business model described in the design document is different from the code model. I think this newcomer is trapped. Which one is right? Will definitely scold my mother. When the business model is the same as the code model, it will greatly reduce the cognitive complexity of our system.

 

2. Complex system design

In order to reduce the complexity of the business system, it is generally through the method of divide and conquer. Nowadays, the popular microservices are split based on the business dimension, so how do they split?

As shown in the figure below, each point represents a domain object. When many objects are mixed together, designers or developers need to understand all domain objects, which undoubtedly increases the complexity. If you can find a way to divide the boundary reasonably, let closely related objects aggregate together (for example, the three aggregates ABC are formed in the figure below), and the aggregates interact through interfaces, then the number of interfaces will be the least. A bit similar to the K-clustering algorithm, you can always find an optimal division method, of course, in many cases rely on the experience of the architect. The bounded context of DDD provides a guiding idea. After the bounded context is divided, a bounded context can correspond to a microservice.

The theory that the establishment of knowledge barriers can improve efficiency is also used here. The person who develops A service does not actually need to understand the internal implementation of B service, but only needs to understand the interface provided by B. The number of domain objects of A service has been greatly reduced. It undoubtedly reduces the complexity.

Take a student management system in a university as an example, it involves the following domain objects: students, teachers, roles, permissions, menus, courses, course scheduling, check-in, etc.

Now let’s divide the bounding context. Because both students and teachers need to log in and permissions, one of our methods of context decomposition is authentication context <role, permission, menu, student, teacher>, teaching context <course, course scheduling, sign-in> .

From the perspective of relevance, these two contexts need 4 interfaces to interact.

Since DDD stipulates that a domain object in the bounding context has a certain meaning, the two students and teachers are a user of the system in the authentication context, and they represent two different identities in the teaching context, that is, when we say As a student, it is uncertain whether it is a user who needs to log in or a student in the lecture, so there is a lack of a domain object user.

After adding the user domain object, the bounded context is re-divided, and only two interfaces are needed for interaction.

   

Three, module coding

The traditional three-tier structure is web, service, and dao. Everyone is familiar with it. A business process that is slightly more complicated will cause the code in the service to become a big ball of mud. In my last job, I saw a service class achieve There are tens of thousands of lines, maintenance and painful, how painful method is, every time you switch to the test, more than 20 bugs will be generated, and new ones will appear after the modification, and it is impossible to converge in a round. I really couldn't stand it, so I applied to the project manager for refactoring. The project manager disagreed. There was no other way but to issue a military order, and I started to do it. In the end, more than 10,000 lines of code became about 4,000 lines, and the bug finally converged.

One way to solve the big mud ball at the service layer is to separate the complexity and divide the service into the application layer and the domain layer. For this content, please refer to Wang Lin's article on infoq

(Https://www.infoq.cn/article/A3cgSUWuRulXHl2c_dUr), an architecture principle mentioned in the article is the separation of business and technology. The domain layer puts business logic, and the application layer puts technical logic. The complexity is reduced, and the domain layer is easier to test.

 

DDD tactical design is to put business logic at the core. The same is true for tidy architecture and hexagonal architecture. Business-related code is written to entities, value objects and domain services, and some technical related codes such as transactions and caching are written to applications. Service inside.

For example, an operation of the shopping cart is to add products to the shopping cart. The application layer ShoppingCartApplicationService handles transactions and caches. The core business logic is in the domain object ShoppingCart.

The domain layer code is as follows:

The application layer code is as follows:

 

 

Four, summary

The unified language of DDD can help better transfer business knowledge in the software development process, bounded context can guide the splitting of complex systems, and tactical design can help code better layering.

Although some companies do not use DDD as a set of combination punches, they may already be using these good methods to develop software. In fact, DDD provides a set of methodology, and it is not necessary to use all of them. You can learn from only some of them. For example, the unified language of DDD improves efficiency by reducing the transfer of business knowledge and can be applied to actual development.

To give a practical example, many internal systems in enterprises also use front-end and back-end separation, and then use front-end development and back-end development to develop separately, and then interface joint debugging. The joint debugging cost is very high. You can change the method to let the back-end Develop as the front end, saving joint debugging costs.

Then some people may have questions here, will the back-end development be inefficient as the front-end? In fact, as long as the front-end provides shelves and front-end components, and then assists some components to use documents and code examples, the back-end development can be started quickly, and the cost of joint debugging will be considerable.

Finally, I want to say that the methodology can provide guidance, but don’t use it mechanically, you need to tailor it according to your own situation and use it flexibly.

——————————  END  ——————————

Recommended in the past

Technical trivia 

Based on distributed design, architecture and system ideas, it also discusses the bits and pieces related to R&D, not limited to code, quality system and R&D management. This number is maintained by the technical team of old drivers at the seat.

Long press to scan code to follow



[Yours is watching, my great encouragement]

Guess you like

Origin blog.csdn.net/u013527895/article/details/109685424