1. What is the responsibility chain design mode

The responsibility chain design mode mainly consists of abstract handler, concrete handler and customer class. When processing the request, the request is sent to the processing link through the customer class, so that all processing objects have the opportunity to process the request and decouple the sender and receiver

In the responsibility chain mode, the customer only needs to send the request to the responsibility chain, and does not need to care about the processing details of the request and the transmission process of the request, so the responsibility chain decouples the sender of the request from the handler of the request.

2. Advantages/disadvantages and usage scenarios of the chain of responsibility model

Advantages of using the chain of responsibility model:

  • Decoupling between sender and receiver processing object classes
  • Encapsulate each processing object, processing class minimum encapsulation principle
  • Can arbitrarily add processing objects, adjust the order between processing objects, improve the maintainability and scalability can be added according to demand processing classes, meet the open and closed principle
  • The flexibility of object responsibility assignment is enhanced. When the process changes, the order of transfer within the chain can be dynamically changed and dynamically added or deleted
  • Chains of responsibility simplify the connection between objects. Each object maintains only one reference to its successors, not all other handlers, which avoids the need for numerous if or if· else statements.
  • Burden sharing. Each class only needs to deal with its own work, should not deal with the next object to complete, clear the scope of responsibility, in line with the single responsibility of the class principle.

Disadvantages of using the chain of responsibility model:

  • There is no guarantee that every request will be processed. Because a request has no clear recipient, there is no guarantee that it will be processed, and the request may not be processed all the way to the end of the chain.
  • For a long chain of responsibilities, the processing of the request may involve multiple processing objects, and the system performance will be affected to some extent.
  • The rationality of responsibility chain establishment depends on the client to ensure, which increases the complexity of the client, and may lead to system errors due to the wrong setting of responsibility chain, such as circular invocation.

Usage Scenarios:

The chain of responsibility pattern can be used when a request comes in and it is not known which specific object (method) or each object needs to handle the request. For example, in the common OA office system, when an employee initiates an application for leave, different encapsulation classes (development group leader, department manager, general manager, etc.) are used to form a processing link, and the processing link is used to process the request initiated by the employee

3. The difference between responsibility chain mode and strategy mode

The policy pattern is similar to the chain of responsibility pattern in that there are multiple objects handling the same request

The difference is that for the same request, the policy mode can choose which specific policy class to process, while the responsibility chain mode cannot determine which class to process according to the request, and the result can be obtained only after all the processing classes on the link are processed once

4. JAVA code demonstration

4.1. Write responsibility chain to handle Handler

package com.zhangsan.shard.handler;

import lombok.Data;

/ * * *@ClassName DutyHandler
 * @Description TODO
 * @Author ZhangSan_Plus
 * @Date2021/9/2 shew forth *@Version1.0 * * /
@Data
public abstract class DutyHandler {
    protected DutyHandler successor;

    /** * leave approval interface **@param message
     * @param days
     * @return boolean
     * @throws
     * @author ZhangSan_Plus
     * @Date2021/9/2 16:56 * * /
    public abstract boolean dutyHandler(String message, Integer days);

}

Copy the code

4.2 Write corresponding implementation for development manager

package com.zhangsan.shard.handler;

/ * * *@ClassName ProcessorOne
 * @Description TODO
 * @Author ZhangSan_Plus
 * @Date7 all 2021/9/2 *@Version1.0 * * /
public class ProcessorOne extends DutyHandler {
    /** * Assume that the development manager can only handle */ if the absence is less than 1 day
    @Override
    public boolean dutyHandler(String message, Integer days) {
        System.out.println("Processing requests:" + message);
        System.out.println("Days of absence:" + days);
        if (days <= 1) {
            System.out.println("Approved by development Manager");
            return true;
        } else {
            System.out.println("If the number of days off is more than one day, the development manager can't handle it, and the project manager can handle it.");
            setSuccessor(new ProcessorTwo());
            System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
            returnsuccessor.dutyHandler(message, days); }}@Override
    public void setSuccessor(DutyHandler dutyHandler) {
        this.successor = dutyHandler;
    }

    @Override
    public DutyHandler getSuccessor(a) {
        returnsuccessor; }}Copy the code

4.3 Write corresponding implementation of project manager

package com.zhangsan.shard.handler;

/ * * *@ClassName ProcessorTwo
 * @Description TODO
 * @Author ZhangSan_Plus
 * @Date2021/9/2 direction for *@Version1.0 * * /
public class ProcessorTwo extends DutyHandler {
    /** * Assume that the project manager can only handle approvals of 10 days or less */
    @Override
    public boolean dutyHandler(String message, Integer days) {
        System.out.println("Processing requests:" + message);
        System.out.println("Days of absence:" + days);
        if (days <= 10) {
            System.out.println("Approved by project Manager");
            return true;
        } else {
            System.out.println("If the number of days of leave is more than ten days, the project manager cannot handle it, and it will be handed over to the general record.");
            setSuccessor(new ProcessorThree());
            System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
            returnsuccessor.dutyHandler(message, days); }}@Override
    public void setSuccessor(DutyHandler dutyHandler) {
        this.successor = dutyHandler;
    }

    @Override
    public DutyHandler getSuccessor(a) {
        returnsuccessor; }}Copy the code

4.4 Write the corresponding implementation of general manager

package com.zhangsan.shard.handler;

/ * * *@ClassName ProcessorThree
 * @Description TODO
 * @Author ZhangSan_Plus
 * @Date2021/9/2 thus * were@Version1.0 * * /
public class ProcessorThree extends DutyHandler {
    /** * The general manager can handle all days of approval */
    @Override
    public boolean dutyHandler(String message, Integer days) {
        System.out.println("Processing requests:" + message);
        System.out.println("Days of absence:" + days);
        System.out.println("Approved by general Manager");
        return true;
    }

    @Override
    public void setSuccessor(DutyHandler dutyHandler) {
        this.successor = dutyHandler;
    }

    @Override
    public DutyHandler getSuccessor(a) {
        returnsuccessor; }}Copy the code

4.5 Prepare employee leave approval simulation

package com.zhangsan.shard.handler;

/ * * *@ClassName Staff
 * @Description TODO
 * @Author ZhangSan_Plus
 * @Date2021/9/2 hast judged *@Version1.0 * * /
public class Staff {
    public static void main(String[] args) {
        ProcessorOne processorOne = new ProcessorOne();
        processorOne.dutyHandler("Zhang SAN submits leave approval".15); }}Copy the code

4.6 Execution results

5. Expansion of the chain of responsibility model

5.1 Pure responsibility chain mode

A pure chain of responsibility pattern requires a specific handler to choose only one of the two behaviors: either to assume full responsibility or to pass responsibility to the next handler. It is not allowed for a specific handler to assume some or all of the responsibility and then pass responsibility down. Moreover, in the pure chain of responsibility pattern, a request must be received by a handler object, and no request can be processed by any handler object. The pure chain of responsibility pattern was applied in the previous purchase order approval example.

5.2 Impure chain of responsibility mode

It is possible for a specific handler object to assume some responsibility for a request and then pass the rest on to the next, and a request may end up not being received by any receiving object.