Design pattern-introduction to the chain of responsibility pattern

Introduction

The Chain of Responsibility Pattern allows multiple objects to have the opportunity to process the request, thereby avoiding the coupling relationship between the sender and receiver of the request. Connect these objects into a chain and pass the request along this chain until an object handles it.

Instance

The chain of responsibility model includes the following roles:

  1. Handler: Abstract processor. Define an interface for processing requests. If necessary, the interface can define a method to set and return a reference to the next home. This role is usually implemented by a Java abstract class or Java interface.
  2. ConcreteHandler: The specific processor. After receiving the request, the specific processor can choose to process the request or pass the request to the next party. Since the specific processor holds a reference to the next home, the specific processor can visit the next home if necessary.
  3. Client: Customer class

Below we take a simple request for leave as an example. Assuming that one day of leave, the project manager can handle it, the three days and so on are handled by the project director, within seven days it is handled by the boss, and the leave is not allowed to exceed seven days. Abstract handler

public abstract class AbstractHandler {
    /**
     * 下一个处理对象
     */
    private AbstractHandler next;
    /**
     * 处理请假
     *
     * @param leaveDays 天数
     * @return 处理结果
     */
    public final String handleLeave(int leaveDays) {
        if (this.getLeaveDays() >= leaveDays) {
            return this.handle();
        } else {
            if (Objects.nonNull(next)) {
                return next.handleLeave(leaveDays);
            } else {
                return "大老板都不能处理你的假期了~~";
            }
        }
    }
    /**
     * 具体处理
     *
     * @return 处理结果
     */
    protected abstract String handle();

    /**
     * 每个处理类能处理的天数,数据可以使数据库获取,这里简单就写死了
     *
     * @return 请假天数
     */
    protected abstract Integer getLeaveDays();

    /**
     * 设置下一个处理类
     *
     * @param next
     */
    public void setNext(AbstractHandler next) {
        this.next = next;
    }
}

Specific handler

// 项目经理处理
public class PMHandler extends AbstractHandler {

    @Override
    protected String handle() {
        return "你的请假被项目经理处理了";
    }

    @Override
    protected Integer getLeaveDays() {
        return 1;
    }
}

// 项目总监处理
public class PDHandler extends AbstractHandler {
    @Override
    protected String handle() {
        return "你的请假被项目总监处理了";
    }

    @Override
    protected Integer getLeaveDays() {
        return 3;
    }
}

// 大老板处理
public class BossHandler extends AbstractHandler {
    @Override
    protected String handle() {
        return "你的请假被大老板处理了";
    }

    @Override
    protected Integer getLeaveDays() {
        return 7;
    }
}

Client

@Test
public void test() {
    PMHandler pmHandler = new PMHandler();
    PDHandler pdHandler = new PDHandler();
    BossHandler bossHandler = new BossHandler();

    pmHandler.setNext(pdHandler);
    pdHandler.setNext(bossHandler);

    String leaveRes = pmHandler.handleLeave(1);
    System.out.println(leaveRes);
    String leaveRes1 = pmHandler.handleLeave(3);
    System.out.println(leaveRes1);
    String leaveRes2 = pmHandler.handleLeave(7);
    System.out.println(leaveRes2);
    String leaveRes3 = pmHandler.handleLeave(8);
    System.out.println(leaveRes3);
}

Class Diagram

image.png

advantage

  1. Reduce coupling. It decouples the sender and receiver of the request;
  2. Simplified the object. So that the object does not need to know the structure of the chain;
  3. Increase flexibility in assigning responsibilities to objects. By changing the members of the chain or mobilizing their order, it is allowed to dynamically add or delete responsibilities;
  4. It is convenient to add new request processing classes.

Disadvantage

  1. The request has no clear recipient, and there is no guarantee that it will be processed. The request may not be processed until the end of the chain;
  2. For a relatively long chain of responsibility, the processing of the request may involve multiple processing objects, and the system performance will be affected to a certain extent, and it is not convenient to debug the code and may cause loop calls.

Applicable scene

  1. There are multiple objects that can handle the same request, and which object handles the request is automatically determined at runtime;
  2. Submit a request to one of multiple objects without clearly specifying the recipient;
  3. A group of objects can be dynamically designated to handle requests.

to sum up

There are two forms of use of the chain of responsibility model: the pure chain of responsibility model and the impure chain of responsibility model.

If a class is either responsible for processing the request or kicking the request to the next ball, it is called the pure responsibility chain model; if a class assumes part of the responsibility and will request to kick the next ball, it is called impure Chain of responsibility model. It is difficult to find practical examples of the pure responsibility chain model, and the commonly seen examples are the realization of the impure responsibility chain model.

Guess you like

Origin blog.csdn.net/doubututou/article/details/109209574