laitimes

System Plastic Surgery: The Application of the Chain of Responsibility Design Model

author:JD Cloud developer

This paper introduces the background and experience of using the chain of responsibility design pattern, so that readers can deepen their impression of this design pattern, and even be inspired to "facelift" the projects they are currently involved in and responsible for, so as to improve the "beauty" of the system. Share the bits and pieces of your work.

1. Background

There is such a module in the system in charge of, partition module, if you look at this word directly, I believe many people will be confused or even misunderstood, in fact, its real meaning is "routing", and then I will briefly describe what is "routing".

I believe we have all had the experience of online shopping, whenever we place an order, we can check the logistics tracking status of the order anytime and anywhere, and the above "routing" concept refers to: the order from A to B transport route line, for example, order order1 to be transported from A to destination F, which can be from A-> B-> D->F, can also be from A->D->F, as for which line should be taken, it is filtered out by the route configured in the system and the corresponding matching rules.

For a long time, the routing configuration and rules in the system are static (the so-called static is configured in advance and almost fixed), the disadvantages of this approach are obvious, that is, the cost can not be controlled, just like the above example, the transportation route obviously has the opportunity to reduce or even can be sent directly (the goods from A to F can be filled with N cars, but they also have to be transported according to the route formulated in the system), but they are limited by the routing rules fixed in the system can only take more roads, which improves the cost of manpower operation and transportation。

Based on this, a big bull has found a business opportunity to reduce costs and increase efficiency: it is to make this routing line and rules move, so that the system can be more flexible and compatible with the above situations, and achieve the maximum use of resources, for example: for example, there are many orders from A to destination F, and only A-> B-> D-> are configured with static lines in the systemF, but after the system monitoring and calculation, it is found that the amount of goods from A to F can be filled with two cars, then at this time, a new line is temporarily generated for these orders from A to F, and at the same time, when receiving and delivering goods at the A site and other practical links involving routing line matching, they are compatible with the scene of this temporary route, so that the overall cost can be reduced without changing user habits, and the efficiency of transportation to the destination has also been greatly improved.

The plan proposed by this big bull is very good, and has been widely recognized and praised by everyone, so it has entered the vigorous development stage after the project is established, and I am fortunate to be entrusted with the important task of leading the development and delivery of this project.

It is worth mentioning that the changes to the routing line run through the entire practical operation process of the order and some functions such as auxiliary queries and statistical reports in the corners and corners, and there are many scenarios involved, so the pressure is still quite large, although there are indeed a lot of detours during the period, but the final result is good, and even after that, there are several similar changes to the demand for routing lines, but based on this transformation, we can easily deal with it, which will be reflected in the follow-up effect of the article.

Having said so much, do you feel that it's actually all nonsense, haha, it's really a bit verbose, let's dream back and forth to reproduce the whole fragmented and rewarding transformation process.

2. Ideas and methods

The partitions mentioned in subsequent articles are the implications of matching rules for routes

First, let's take a look at a simple diagram of the practical process

System Plastic Surgery: The Application of the Chain of Responsibility Design Model

In the actual operation process of each site, the partition matching rules will be involved, and at the same time, the routing matching rules will also be involved in the query function or report function of some auxiliary practical operations, so once the partition matching rules are to be changed, then the following pain points will be faced

◦First of all, at the business level, almost the entire process will be run, whether it is evaluation, development, testing and other links, there will be a huge workload

◦From a system perspective, the current status of this part of the code is also very unfriendly, mainly reflected in:

▪ The core business rules of partition matching are the same, but the code is written differently and is scattered, making it difficult to read and maintain, and there is a risk of missing scenarios

▪ At present, the partition matching function is written by each instance and coupled to each usage scenario, which is not scalable, and once the rules change, the change cost is very high

Based on the above pain points, I decided to reconstruct and rectify this module, firstly, to improve myself through this challenge, and secondly, to pave the way for the possibility of changing the rules again in the future, so what should I do to solve the pain points mentioned above?

1. Do a full evaluation at the business level: reflected in the detailed design of the development (here because I am very familiar with the business rules, so it is my advantage), such as scene combing, modification scheme, and even sinking to the specific function in the design (button clicking, enter the input box after the input of the input box, etc.) to modify the logic scheme and code position, so that all participating developers can use this as a guide manual for rapid development, and testers can use this as a guide for use case writing. Product people use it as a dictionary to deepen their own understanding of the business, and so on. Doesn't it sound very bull X, wahaha, it's a bit of a boast here, this article will not focus on here, mainly to introduce the design pattern, let's slowly continue to look down

2. Here is our highlight, the system level is mainly reflected in the code, after all, no matter how good it is, if you can't implement the code, you can't see the effect is in vain, not to mention that we are a position again, okay, don't talk nonsense, continue to watch me perform haha

▪ First of all, the partition matching core module is unified and only one instance is retained in the system for service provision, which can not only solve the problem of high maintenance cost of code dispersion, but also avoid the risk of scene omission

Seeing this, some people may say, will you bring another problem: although the scene will not be missed, a code change has been reached, and the scene will take effect everywhere, but will it change the original functional characteristics of some scenes? This is more abstract, for example: for example, the general scenario rule is that all orders are transported according to the partition rules of the established configuration of the system, but now some merchants have opened some services to the destination quickly, so the orders of these merchants cannot be partitioned and matched with the existing general rules, and the partition matching should be carried out according to the new rules to achieve the purpose of fast transportation. That's the difference.

▪ Reuse existing data structures, add partition types, and adjust the corresponding SQL and Service services (which is not the focus of this article), and support the expansion of partition rules on the basis of compatibility with existing production logic

▪ Adjust the code structure of partition matching rules in combination with the idea of design patterns: adopt the chain of responsibility pattern (here is the focus of this article)

So what exactly is the chain of responsibility model?

The definition given by Da Niu is to give multiple objects a chance to process the request, thus avoiding the coupling relationship between the sender and receiver of the request. String these objects together and pass the request along that chain until an object processes it.

Combined with the actual business of the existing system, let's talk about how I apply it: in the background of the opening paragraph, I have introduced that the existing partition matching rules are static partition matching (such as a certain business point-to-point, A certain business point to the scope of the area, etc., the specific business rules will not be expanded, as long as you know that there are a lot of matching rules here), now to add a new rule to support dynamic (also a variety of matching, I will not expand on it), here I define each partition rule as a partition type, and each partition type is defined as a partition node, these nodes are threaded into a chain, so that each request in this chain to find its own line for transportation.

Due to the sensitivity of the business rules, they will not be specifically disclosed in the article, which will not affect the application understanding of key design patterns

Combined with the definition and the above analysis, is it suitable to use the chain of responsibility design model in the actual situation? First of all, the advantages of using this mode are as follows:

◦Separation of request and processing (free from coupling with business practice, no need to care about how the request comes from, only focus on matching partition rules)

◦Improved flexibility and scalability of the system (with new rules, only need to add nodes)

Of course, this model also has some disadvantages: when the chain of responsibility is relatively long, because each request will traverse the entire chain, there may be performance problems, and it will also feel more complicated to debug for students who do not understand the business.

On the whole, the advantage is that it solves our current pain points and is conducive to subsequent expansion, while the performance part of the disadvantage can be pulled by combining the reserved hook function in the template pattern (if the current request is not suitable for the current partition node rules, it will be skipped) to minimize the impact of performance problems, and at the same time, based on the developer's understanding of the business, it should also be. In this way, it seems that the overall advantages outweigh the disadvantages.

With all that said, let's take a look at a simple comparison of the partition modules before and after the transformation

System Plastic Surgery: The Application of the Chain of Responsibility Design Model

Although the diagram is very simple, the meaning of the comparison is still obvious, before the transformation: partition matching and business processing are coupled together, after the transformation: partition matching is a chain and there is no business logic processing in it, which is freed from coupling and supports expansion. Some people will wonder when they see this: Didn't it say above that there is only one new dynamic matching rule, why are there so many nodes in the chain, and there are still two chains. Let me explain here a little: the current two chains have undergone many requirements version changes, and the difference seems to be not big at the moment, mainly because the two chains abstracted from the different specified scenarios of the source business they provide do not interfere with each other's operation, and the nodes introduced in this article in many places are also added later, and the node rules that are still used in the system until now (this is what I mentioned at the beginning of the article: in case there are rule changes later). Sure enough, it was still as witty as I was, and the "prophecy" came true, and in the effect I will say the importance of supporting expansion here to shorten the construction period)

3. Practice process

I believe that many readers will find that the above is said to be a unified closure, and it is also said that the template mode is combined to avoid the performance impact to the greatest extent, so your chain of responsibility and a design pattern cannot support it.

That's right, you're right, it's smart, it's true that just using a single chain of responsibility design pattern is far from achieving the effect mentioned above, here we do use a combination of factories, templates, and chain of responsibility patterns, the factory is used to obtain the bean of the chain, the template is used to set up general methods, calls between methods, and methods reserved for subclass implementations, such as switches, pre- and post-processing, differentiation, etc., and the chain of responsibility is used to combine each node

System Plastic Surgery: The Application of the Chain of Responsibility Design Model

This paragraph is relatively simple, after all, it is the code, the above class diagram is almost the practical application in the code, and it is also the core part of the code, and in the actual call, it is through the factory to obtain the bean chain for specific partition matching.

Fourth, the reflection on the practice process and the evaluation of the effect

The results after the transformation are mainly reflected in the follow-up expansion and maintenance, as mentioned at the beginning of the article, once the partition matching rules are to be changed, they will face two pain points, the most direct embodiment is in the construction period, the first time to receive the change of this block when the new routing rule requirements, the overall actual construction period is 45 days on the R&D side, not to mention that once the BUG is encountered, the test duration is not guaranteed (corresponding to the dynamic node in the node in the figure above)

System Plastic Surgery: The Application of the Chain of Responsibility Design Model

But it didn't take long for the new requirements of the matching rules to be added again (corresponding to the arrival carpool node in the node in the above figure), the same kind of demand, the construction period was shortened by nearly half, and the optimal 45 days were reduced to 27 days, which also included the transformation of other non-partitioned modules in this requirement, of course, the transformation of the first version did have some perfect places, and the requirements were optimized after this time

System Plastic Surgery: The Application of the Chain of Responsibility Design Model

The next two really reflect what is called the duration disappearing technique, one is the first board partition rule requirement, and the other is the direct delivery partition rule in the recent B-network convergence requirement

◦The construction period of the direct hair partition is 2 days

◦The construction period of the first board partition is 1 day

To be honest, I didn't expect such a big effect when I didn't look back at the data, and now I look back and I'm stunned, who would have thought that an application of design patterns could shorten the construction period from 45 days to 1 day, which is incredible.

Of course, there are some places that can be improved and upgraded, at present, the assembly of the chain of responsibility nodes is manually specified, which can be changed to automatic assembly (I have already achieved it in the transformation in another business scenario, and the synchronous transformation will be carried out here), and the other is to control the number of nodes, if the number is too large, you may need to consider compatibility schemes.

As the saying goes, a drop of water through the stone is not a day's work, freezing three feet is not a day's cold, the pursuit of powerful tools, novel technology is feasible, but do not forget the daily work of a little bit of small changes, in a short period of time may not see anything, once the quantitative change caused the qualitative change, I believe that the result will be very impressive.

Read on