introduce

  1. The Chain of Responsibility Pattern creates a Chain of recipient objects for the requester, which decouples the request from the sender and requester.
  2. The chain of responsibility pattern typically involves each receiver containing a reference to another receiver, and if an object cannot handle the request, it will then pass the same request to the next receiver to decouple, and so on.
  3. This type of design pattern is behavioral.

  • Handler: Abstract Handler that defines a class as an interface to handle requests and also as an additional Handler
  • ConcreteHandler: a ConcreteHandler that handles the request it is responsible for, accesses its successors, if it can handle the request, or forwards it to its successors otherwise.

case

OA system procurement approval project

  1. Purchasers purchase company supplies
  2. If the amount is less than or equal to 5000, it shall be approved by the group leader.
  3. If the amount is less than or equal to 10000, submit it to project manager for approval.
  4. If the amount is less than or equal to 30000, it will be approved by the director.
  5. If the value is greater than 30000, it should be approved by the general manager.

Creating an Approval Object

@Data
@ToString
public class PurchaseRequest {

    private Integer type;

    private BigDecimal price;

    private Integer id = 0;

    public PurchaseRequest(Integer type, BigDecimal price, Integer id) {
        this.type = type;
        this.price = price;
        this.id = id; }}Copy the code

The abstract approval class Approver is equivalent to the Handler in the chain of Responsibility pattern

public abstract class Approver {

    /** ** next handler */
    Approver approver;

    /** * name */
    String name;

    public Approver(a) {}public Approver(String name) {
        this.name = name;
    }

    public Approver getApprover(a) {
        return approver;
    }

    public void setApprover(Approver approver) {
        this.approver = approver;
    }

    /** ** Method of processing approval *@param purchaseRequest
     */
    public abstract void processRequest(PurchaseRequest purchaseRequest);
}

Copy the code

The leader approval class DepartmentApprover is equivalent to the ConcreteHandler in the Chain of responsibility pattern

public class DepartmentApprover extends Approver{

    public DepartmentApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice().compareTo(new BigDecimal("5000.00"= = -))1){
            System.out.println("The current ID"+purchaseRequest.getId()+"Be"+this.name+"Processing");
        }else{ approver.processRequest(purchaseRequest); }}}Copy the code

The Department Manager approval class PmApprover is equivalent to the ConcreteHandler in the Chain of Responsibility pattern

public class PmApprover extends Approver{

    public PmApprover(String name) {
        super(name);
    }
    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice().compareTo(new BigDecimal("10000.00"= = -))1){
            System.out.println("The current ID"+purchaseRequest.getId()+"Be"+this.name+"Processing");
        }else{ approver.processRequest(purchaseRequest); }}}Copy the code

The Department Director approval class MdApprover is equivalent to the ConcreteHandler in the Chain of Responsibility pattern

public class MdApprover extends Approver{

    public MdApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice().compareTo(new BigDecimal("30000.00"= = -))1){
            System.out.println("The current ID"+purchaseRequest.getId()+"Be"+this.name+"Processing");
        }else{ approver.processRequest(purchaseRequest); }}}Copy the code

The General Manager approval class GmApprover is equivalent to the ConcreteHandler in the Chain of Responsibility pattern

public class GmApprover extends Approver{

    public GmApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if(purchaseRequest.getPrice().compareTo(new BigDecimal("30000.00")) = =1){
            System.out.println("The current ID"+purchaseRequest.getId()+"Be"+this.name+"Processing"); }}}Copy the code

The client

public class Client {

    public static void main(String[] args) {
        PurchaseRequest purchaseRequest = new PurchaseRequest(1.new BigDecimal("3000"),1);
        DepartmentApprover departmentApprover = new DepartmentApprover("Group Leader Zhang");
        PmApprover pmApprover = new PmApprover("Manager Zhang");
        MdApprover mdApprover = new MdApprover("Director Li");
        GmApprover gmApprover = new GmApprover("General Manager Li"); departmentApprover.setApprover(pmApprover); pmApprover.setApprover(mdApprover); mdApprover.setApprover(gmApprover); departmentApprover.processRequest(purchaseRequest); }}Copy the code

Advantages and disadvantages

Advantages:

1) Separate request and processing to achieve decoupling and improve system flexibility 2) simplify objects so that they do not need to know the chain structureCopy the code

Disadvantages:

1) Performance is affected, especially when chains are long and 2) there is no guarantee that requests will be receivedCopy the code

Applicable scenarios:

1) There are multiple objects that can handle the same request: multilevel requests, leave/raise requestsCopy the code



Note: this is the end of 23 design modes! It’s going to get better and better

Github Demo address: ~ ~ ~ portal ~ ~ ~

Personal blog address: blog.yanxiaolu.cn /