Chain of Responsibility Model (26)

Believe in yourself, please believe in yourself

The previous chapter briefly introduced the strategy pattern (25), if you haven’t read it, please watch the previous chapter

1. Chain of Responsibility Model

Refer to the introduction of the chain of responsibility pattern in the rookie tutorial: https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

As the name suggests, the Chain of Responsibility Pattern creates a chain of receiver objects for a request.

This pattern decouples the sender and receiver of the request given the type of the request. This type of design pattern is a behavioral pattern.

In this pattern, typically each receiver contains a reference to another receiver.

If an object cannot handle the request, it passes the same request to the next recipient, and so on.

1.1 Introduction

Intent: To avoid the coupling of the request sender and the receiver, make it possible for multiple objects to receive the request, connect these objects into a chain, and pass
the request along this chain until an object processes it.

Main solution: The processor on the responsibility chain is responsible for processing the request. The customer only needs to send the request to the responsibility chain, and
does not need to care about the processing details and delivery of the request. Therefore, the responsibility chain will send the request to the request processor. decoupled.

When to use: To filter many channels when processing messages.

How to solve: All intercepted classes implement a unified interface.

Key code: Aggregate itself in the Handler, judge whether it is suitable in the HandlerRequest, and pass it down if the condition is not met, and
set it before passing it to whom.

Applications:

1. "Drumming and Passing Flowers" in Dream of Red Mansions.

2. Event bubbling in JS.

3. Encoding processing by Apache Tomcat in JAVA WEB, interceptor of Struts2, Filter of jsp servlet.

advantage:

1. Reduce coupling. It decouples the sender and receiver of a request.

2. The object is simplified. So that the object does not need to know the structure of the chain.

3. Enhance the flexibility of assigning responsibilities to objects. By changing the members in the chain or mobilizing their order, it is allowed to dynamically add or delete responsibilities.

4. It is very convenient to add a new request processing class.

shortcoming:

1. There is no guarantee that the request will be accepted.

2. The system performance will be affected to a certain extent, and it is not convenient to debug the code, which may cause circular calls.

3. It may not be easy to observe the characteristics of the runtime, which hinders debugging.

scenes to be used:

1. There are multiple objects that can handle the same request, and the specific object that handles the request is automatically determined at runtime.

2. Submit a request to one of multiple objects without explicitly specifying the receiver.

3. A group of objects can be dynamically specified to process requests.

Note: Many applications are encountered in JAVA WEB.


composition role specific relation
request BuyAudit Contains many attributes, representing a request
Abstract handler (Handler) Approver To process the request that it is responsible for, you can access its successor (that is, the next processor).
If the current request can be processed, it will be processed, otherwise, the request will be handed over to the successor for processing, thus forming a chain of responsibility
Concrete handler (ConcreteHandler) Zhu Ren, Yuan Zhang It will hold a reference to an abstract role internally and call it to the client

image-20230615204310121

2. Examples of Chain of Responsibility

2.1 Request BuyAudit

@Data
public class BuyAudit {
    
    
    private Integer id;
    private Float price;
}

2.2 Abstract processor Approver

@Data
public abstract class Approver {
    
    
    private Approver next;
    private String name;

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

    public abstract void processRequest (BuyAudit buyAudit) ;

}

2.3 Specific handlers

Two. Three. One Director

@Slf4j
public class ZhuRen extends Approver{
    
    
    public ZhuRen (String name) {
    
    
        super(name);
    }
    @Override
    public void processRequest(BuyAudit buyAudit) {
    
    
        if (buyAudit.getPrice() < 5000) {
    
    
            log.info("请求{} 金额是 {} 被用户 {} 处理", buyAudit.getId(),buyAudit.getPrice(),this.getName());
        }else {
    
    
            // 交给下一个人进行处理
            log.info("用户 {} 无法处理这么大的金额申请,往上抛出 ", this.getName());
            super.getNext().processRequest(buyAudit);
        }
    }
}

2.3. Second Dean Yuan Zhang

@Slf4j
public class YuanZhang extends Approver{
    
    
    public YuanZhang(String name) {
    
    
        super(name);
    }
    @Override
    public void processRequest(BuyAudit buyAudit) {
    
    
        if (buyAudit.getPrice() < 10000) {
    
    
            log.info("请求{} 金额是 {} 被用户 {} 处理", buyAudit.getId(),buyAudit.getPrice(),this.getName());
        }else {
    
    
            // 交给下一个人进行处理
            log.info("用户 {} 无法处理这么大的金额申请,往上抛出 ", this.getName());
            super.getNext().processRequest(buyAudit);
        }
    }
}

2.3.3 Deputy Principal FuXiaoZhange

@Slf4j
public class FuXiaoZhange extends Approver{
    
    
    public FuXiaoZhange(String name) {
    
    
        super(name);
    }
    @Override
    public void processRequest(BuyAudit buyAudit) {
    
    
        if (buyAudit.getPrice() < 30000) {
    
    
            log.info("请求{} 金额是 {} 被用户 {} 处理", buyAudit.getId(),buyAudit.getPrice(),this.getName());
        }else {
    
    
            // 交给下一个人进行处理
            log.info("用户 {} 无法处理这么大的金额申请,往上抛出 ", this.getName());
            super.getNext().processRequest(buyAudit);
        }
    }
}

2.3.4 Principal Xiao Zhange

@Slf4j
public class XiaoZhange extends Approver{
    
    
    public XiaoZhange(String name) {
    
    
        super(name);
    }
    @Override
    public void processRequest(BuyAudit buyAudit) {
    
    
        log.info("请求{} 金额是 {} 被用户 {} 处理", buyAudit.getId(),buyAudit.getPrice(),this.getName());
    }
}

2.4 Client calls

@Test
    public void oneTest() {
    
    
        // 定义责任链用户
        Approver zhuRen = new ZhuRen("主任");
        Approver yuanZhang = new YuanZhang("院长");
        Approver fuXiaoZhang = new FuXiaoZhange("副校长");
        Approver xiaoZhange = new XiaoZhange("校长");

        zhuRen.setNext(yuanZhang);
        yuanZhang.setNext(fuXiaoZhang);
        fuXiaoZhang.setNext(xiaoZhange);

        // 定义一个请求
        BuyAudit buyAudit = new BuyAudit();
        buyAudit.setId(1);
        buyAudit.setPrice(15000.0f);
        log.info(">>> 处理 15000 的请求申请");
        //从最低的开始进行处理请求
        zhuRen.processRequest(buyAudit);
        buyAudit.setPrice(45000.0f);
        log.info(">>> 处理 45000 的请求申请");
        zhuRen.processRequest(buyAudit);
    }

image-20230615205041821


The code for this chapter is placed on github:


https://github.com/yuejianli/DesignPattern/tree/develop/Chain


Thank you for watching, if you like it, please follow me, thank you again!!!

Guess you like

Origin blog.csdn.net/yjltx1234csdn/article/details/131235677