1. The concept of responsibility chain model
The responsibility chain model is an object's behavior model.In the responsibility chain model, many objects are linked together to form a chain by each object's reference to its subordinates.Requests are passed along this chain until an object in the chain decides to process the request.The client making the request does not know which object in the chain will ultimately process the request, which allows the system to dynamically reorganize and assign responsibility without affecting the client.
2. When to use the responsibility chain model
According to conceptual understanding, the responsibility chain model is a model that can handle a single request flow, similar to a business workflow, and the responsibility chain can dynamically adjust the various links in the process.
That is, if there is such a business that needs to be handled step by step in the business, try using the responsibility chain model.
In my projects, I typically use workflow patterns when I need to make business decisions step by step, for example:
The http request interceptor first determines whether the protocol of HttpHeader is correct, whether the login information is correct, whether the request content is correct, etc. These steps can be implemented with the responsibility chain mode.
From a code structure perspective, you can solve the problem of nested if, for example:
if (Validation Protocol) { .... if (authentication) { .... if (validation data) { .... } } }
This nested if structure can be avoided and code readability can be improved.Next, try implementing the responsibility chain pattern in Java code.
3. How to Use the Responsibility Chain Model
3.1 Implementation
Taking the request interceptor as an example, a responsibility chain model is simulated and validated in three steps:
- Verify that the protocol is correct;
- Verify that the login information is correct;
- Verify that the requested data is correct;
Here are the class diagrams and codes:
// Abstract Class of Responsibility Chain Pattern public abstract class Validator { // Next step in setting up the responsibility chain private Validator next; public Validator setNext(Validator next) { this.next = next; // Go back to the next step and do chain setup return next; } // Beginning of Chain of Responsibility Processing public final void handler(List<String> context) { if (!resolve(context)) { // Determine if the processing result failed, and if it failed, do not go down fail(context); } else if (next != null) { // If this process is successful, determine if there is still the next step, and if so, execute the handler for the next step next.handler(context); } else { // If the process succeeds, there is no next step and the responsibility chain ends success(context); } } // A business-specific approach, defining an abstract method to be implemented by a subclass (similar to a template method pattern) protected abstract boolean resolve(List<String> context); // Processing Successfully Passed protected void success(List<String> context) { System.out.println("Validation passed."); } // Handling that failed to pass protected void fail(List<String> context) { System.out.println("Validation failed."); } } // Processing Classes for Verifying Authentication public class AuthValidator extends Validator { public boolean resolve(List<String> context) { return context.get(1).equals("admin"); } } // Processing Class for Validation Protocol public class ProtocolValidator extends Validator { public boolean resolve(List<String> context) { return context.get(0).equals("http"); } } // Processing classes for validating data public class DataSecurityValidator extends Validator { public boolean resolve(List<String> context) { return context.get(2).equals("hello"); } }
The above is the class diagram and code of the responsibility chain pattern. From the code point of view, the abstract class defines the creation method of the responsibility chain and the method of circular invocation, but the specific processing requires the implementation of subclasses (similar to the template method), and then, in the case of success or failure, the related processing, the use of the responsibility chain pattern is as follows:
public class Client { public static void main(String[] args) { // Because it is a test, the relationship of the responsibility chain is configured here. Client normally does not need to know the configuration relationship of the responsibility chain Validator protocolValidator = new ProtocolValidator(); Validator authValidator = new AuthValidator(); Validator dataSecurityValidator = new DataSecurityValidator(); protocolValidator.setNext(authValidator).setNext(dataSecurityValidator); // Processing, simulation validation passed List<String> params1 = new ArrayList<String>(); params1.add("http"); params1.add("admin"); params1.add("hello"); protocolValidator.handler(params1); // Processing, simulation validation failed List<String> params2 = new ArrayList<String>(); params2.add("http"); params2.add("ss"); params2.add("hello"); protocolValidator.handler(params2); } }
Links are first established through setNext, then handler is invoked from a node (usually the first node) for business processing.
This is the Java code implementation of the responsibility chain pattern.
3.2 Benefits of the responsibility chain model
The benefits of the chain of responsibility model are as follows:
- High readability: Nested judgment blocks are optimized in an object-oriented way to achieve a semantic effect through good naming;
- Flexibility: You can configure the relationship between the front and back of each judgment link through setNext at will, without modifying the code, nested if is not possible;
- Extensibility: If there are subsequent changes in requirements, you can quickly read the new responsibility chain link without modifying the original code, in line with the open and close principle;
4. Summary
Responsibility chain model, the face of the business scenario is relatively single, it is better to determine what business scenario to use.However, the code implemented is slightly more complex and understandable than other design patterns.
Another hidden advantage of the responsibility chain model is that it weakens the previous association between the caller (Client) and the processor (Validator). The caller does not need to know the relationship between each link of the responsibility chain, but simply calls the hanlder method of the responsibility chain. This decoupling advantage is important.
Above are some of my understandings of the responsibility chain model, there are some deficiencies, please point out, thank you.