Chain of Responsibility Pattern: Avoid coupling requests between senders and receivers, make it possible for multiple objects to receive requests, connect these objects into a chain, and pass requests along this chain until an object processes it. Responsibility chain model is an object behavior model.
The responsibility chain model includes the following roles:
Handler: It defines an interface for processing requests, which is generally designed as an abstract class. Because different specific processors handle requests differently, they define abstract request processing methods. Because each handler's next home is still a handler, an abstract handler type object (such as successor in the structure diagram) is defined as its reference to the next home. With this reference, processors can be linked into a chain. ConcreteHandler (Specific Processor): It is a subclass of abstract processors, which can handle user requests. It implements Abstract request processing methods defined by abstract processors in concrete processors. Before processing requests, it needs to be judged to see if there are corresponding processing privileges. If the request can be processed, it will be processed, otherwise the request will be forwarded to successors. The next object in the chain can be accessed by the volume handler for request forwarding.
1. Main Advantages
(1) The responsibility chain model makes it unnecessary for an object to know which other object is handling its request. The object only needs to know that the request will be processed. The receiver and the sender have no clear information about each other, and the object in the chain does not need to know the structure of the chain. The client is responsible for the creation of the chain, which reduces the coupling of the system. (2) The request processing object only needs to maintain a reference to its successors, but does not need to maintain its reference to all candidate processors, which can simplify the interconnection of objects. (3) When assigning responsibilities to the object, the responsibility chain can give us more flexibility. We can increase or change the responsibility of handling a request by dynamically adding or modifying the chain at run time. (4) When adding a new specific request handler to the system, it is not necessary to modify the code of the original system, but only to rebuild the chain on the client side. From this point of view, it conforms to the "open-close principle".
2. Main shortcomings
(1) Since a request does not have a clear recipient, it cannot be guaranteed that it will be processed. The request may not be processed until the end of the chain; a request may not be processed because the responsibility chain is not properly configured. (2) For a long chain of responsibility, the processing of requests may involve multiple processing objects, which will affect the system performance to a certain extent, and it is not convenient to debug the code. (3) If the chain is not built properly, it may cause circular calls, which will cause the system to fall into a dead cycle.
3. Applicable Scenario
(1) There are many objects that can handle the same request. The specific object that handles the request is to be determined when it runs. The client only needs to submit the request to the chain, without having to care about who the object of the request is and how it is handled. (2) Submit a request to one of multiple objects without explicitly specifying the recipient. (3) A group of objects can be dynamically designated to process requests. Clients can dynamically create a chain of responsibility to process requests. They can also change the order of processors in the chain.
Chain of Responsibility in the Glory of the King (segment):
/** * 2018/12/6 * Abstract processor * * @author machuanpeng */ public abstract class Handler { //Maintain references to inferiors protected Handler successor; public void setSuccessor(Handler successor) { this.successor=successor; } public abstract void handleRequest(int star); }
/** * 2018/12/6 * Bronze Handler * * @author machuanpeng */ public class QingTongHandler extends Handler { public void handleRequest(int star) { if (star<10) { System.out.print("Bronze segment"); } else { //Forwarding request this.successor.handleRequest(star); } } }
/** * 2018/12/6 * Silver dealer * * @author machuanpeng */ public class BaiYinHandler extends Handler { public void handleRequest(int star) { if (star<25) { System.out.print("Silver segment"); } else { //Forwarding request this.successor.handleRequest(star); } } }
/** * 2018/12/6 * Other specific handlers * * @author machuanpeng */ public class QiTaHandler extends Handler { public void handleRequest(int star) { System.out.print("Other segments"); } }
Test:
public class Client { public static void main(String args[]) { Handler qingTong = new QingTongHandler(); Handler baiYin = new BaiYinHandler(); Handler qiTa = new QiTaHandler(); qingTong.setSuccessor(baiYin); baiYin.setSuccessor(qiTa); qingTong.handleRequest(9); qingTong.handleRequest(20); qingTong.handleRequest(30); } }