[Java design pattern] Java design pattern (5) Chain of Responsibility Pattern (Chain of Responsibility Pattern)

Contents of this article

1. Introduction to the Chain of Responsibility Model

Second, the code implementation

2.1 Business logic

2.2 Code implementation


As the name implies, the Chain of Responsibility Pattern creates a chain of recipient objects for the request. This mode gives the type of request and decouples the sender and receiver of the request. This type of design pattern is a behavioral pattern.

In this model, usually each recipient contains a reference to another recipient. If an object cannot handle the request, it will pass the same request to the next recipient, and so on.

1. Introduction to the Chain of Responsibility Model

Intent: To avoid coupling the request sender and receiver together, 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 handles it.

The main solution: the processor in the responsibility chain is responsible for processing the request, and 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 transfer of the request, so the responsibility chain will be the sender of the request and the processor of the request Decoupled.

When to use: Filter many channels when processing messages.

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

Key code: Handler aggregates itself, judges whether it is appropriate in HandlerRequest, and passes it down if the conditions are not met, and sets it in before passing it to whom.

Application examples: 1. "Drumming to pass flowers" in the Dream of Red Mansions. 2. Events bubbling in JS. 3. The processing of Encoding by Apache Tomcat in JAVA WEB, the interceptor of Struts2, and the Filter of jsp servlet.

Advantages: 1. Reduce the degree of coupling. It decouples the sender and receiver of the request. 2. Simplify the object. 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 of the chain or mobilizing their order, it is allowed to dynamically add or delete responsibilities. 4. It is very convenient to add new request processing classes.

Disadvantages: 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 loop calls. 3. It may not be easy to observe the characteristics at runtime, which hinders debugging.

Usage scenarios: 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 process the request.

Note: There are many applications in JAVA WEB.

Second, the code implementation

The code implementation examples of all design patterns can be viewed on Code Cloud, and those who are interested can check it. Code Cloud address: https://gitee.com/no8g/java-design-patterns

2.1 Business logic

In ancient China, the ethics of "three obediences and four virtues" was formulated for women. "Three obediences" refers to "following the father if not married, following the husband if married, and following the son if the husband died." Father, obey the husband after getting married, and obey the son even when the husband is dead. For example, a woman who wants to go out shopping, the same kind of request, she must obtain the consent of her father before she marries, and must obtain the permission of her husband after marrying. What if the husband dies? Generally, men die earlier than women, and they have to ask their sons if they allow themselves to go out shopping. Maybe you are going to ask what should you do if you don’t have a son. Ask my brother-in-law, nephew, etc. In patrilineal society, women only occupy a subordinate position. Now thinking about women in China, it is still relatively miserable. You have to ask for instructions when you go shopping. There are only two choices as fathers, husbands, and sons: or take responsibility. Tell her to allow or not to go shopping, or ask her to ask the next person, this is the constraint of the entire social system.

Applied to our project are business rules, then let’s see how to implement the "three compliances" through our program. The requirements are very simple: describe the ancient women’s "three compliances" system through the program, so let’s look at the class diagram first:

We can abstract into such a structure, the female request is first sent to the father class, and the father class sees that it needs to be processed by itself, and responds to it. If the daughter is already married, then the request should be forwarded to the son-in-law for processing. Once the son-in-law goes to heaven to report, the son will handle the request, similar to this request:

Each node of father, husband, and son has two choices: either take the responsibility and make a response; or forward the request to the subsequent link. The structure analysis is already very clear, then let's see how to implement this function, first look at the class diagram:

From the class diagram, the three implementation classes Father, Husband, and Son only need to implement the constructor and the abstract methods of the parent class. How to handle these requests has been transferred to the Hanlder abstract class. Let’s see how Hanlder achieve:

The result is also correct, the business call class Client does not need to judge who needs to process it, and the subclasses of the Handler abstract class can continue to be added in the future, but our delivery chain is increased, and the calling class does not need to understand the change process, or even There is no need to know who is handling this request.

The above explanation is the responsibility chain model. Look at whether the three categories of Father, Husband, and Son are being passed when processing women’s requests. Each link has only two options: either take responsibility and respond, or pass it down. Request, there will eventually be a link to respond, the general class diagram is as follows:

2.2 Code implementation

package com.iot.practice.designpattern.chainofresponsibility.chainofresponsibilitypattern;

import com.iot.practice.designpattern.chainofresponsibility.IWomen;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * <p>Client 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 11:37</p>
 * <p>@remark:</p>
 */
public class ChainOfResponsibilityClient {

    public static void main(String[] args) {
        // 随机挑选几个女性
        Random random = new Random();
        List<IWomen> iWomenList = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            iWomenList.add(new IWomenImpl(random.nextInt(4), "我要看电影"));
        }

        // 定义三个请示对象
        Handler father = new Father();
        Handler husband = new Husband();
        Handler son = new Son();

        // 设置请示顺序
        father.setNext(husband);
        husband.setNext(son);

        for (IWomen iWomen : iWomenList) {
            father.HandleMessage(iWomen);
        }
    }
}

 

package com.iot.practice.designpattern.chainofresponsibility.chainofresponsibilitypattern;

import com.iot.practice.designpattern.chainofresponsibility.IWomen;

/**
 * <p>Handler 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 10:56</p>
 * <p>@remark:
 * 有没有看到,其实在这里也用到模版方法模式,在模版方法中判断请求的级别和当前能够处理的级别,
 * 如果相同则调用基本方法,做出反馈;如果不相等,则传递到下一个环节,由下一环节做出回应。基本方
 * 法 response 要各个实现类都要实现,我们来看三个实现类:
 * </p>
 */
public abstract class Handler {

    /**
     * 能处理的级别
     */
    private int level = 0;

    /**
     * 责任传递,下一个人责任人是谁
     */
    private Handler nextHandler;

    /**
     * 构造函数:每个类都要说明一下自己能处理哪些请求
     *
     * @param level 能处理的级别
     */
    public Handler(int level) {
        this.level = level;
    }

    /**
     * 一个女性(女儿,妻子或者是母亲)要求逛街,你要处理这个请求
     *
     * @param iWomen 女性统称
     */
    public final void HandleMessage(IWomen iWomen) {
        if (iWomen.getType() == this.level) {
            this.response(iWomen);
        } else {
            // 有后续环节,才把请求往后递送
            if (this.nextHandler != null) {
                this.nextHandler.HandleMessage(iWomen);
            } else {
                // /已经没有后续处理人了,不用处理了
                System.out.println("-----------没地方请示了,不做处理!---------\n");
            }
        }
    }

    /**
     * 如果不属于你处理的返回,你应该让她找下一个环节的人,比如
     * 女儿出嫁了,还向父亲请示是否可以逛街,那父亲就应该告诉女儿,应该找丈夫请示
     *
     * @param handler 处理类
     */
    public void setNext(Handler handler) {
        this.nextHandler = handler;
    }

    /**
     * 有请示那当然要回应
     *
     * @param iWomen 女性统称
     */
    public abstract void response(IWomen iWomen);
}
package com.iot.practice.designpattern.chainofresponsibility;

/**
 * <p>IWomen 此接口用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 9:55</p>
 * <p>@remark:古代悲哀女性的总称</p>
 */
public interface IWomen {

    /**
     * 获得个人状况
     *
     * @return 个人状况数值
     */
    public int getType();

    /**
     * 获得个人请示,你要干什么?出去逛街?约会?还是看电影
     *
     * @return 干什么
     */
    public String getRequest();
}
package com.iot.practice.designpattern.chainofresponsibility.chainofresponsibilitypattern;

import com.iot.practice.designpattern.chainofresponsibility.IWomen;

/**
 * <p>IWomenImpl 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 11:23</p>
 * <p>@remark:</p>
 */
public class IWomenImpl implements IWomen {

    /**
     * 通过一个int类型的参数来描述妇女的个人状况
     * 1---未出嫁
     * 2---出嫁
     * 3---夫死
     */
    private int type = 0;

    /**
     * 妇女的请示
     */
    private String request = "";

    /**
     * 构造函数传递过来请求
     *
     * @param type    个人状况
     * @param request 妇女的请示
     */
    public IWomenImpl(int type, String request) {
        this.type = type;
        this.request = request;
        // 为了显示好看点,我在这里做了点处理
        switch(this.type) {
            case 1:
                this.request = "女儿的请求是:" + request;
                break;
            case 2:
                this.request = "妻子的请求是:" + request;
                break;
            case 3:
                this.request = "母亲的请求是:" + request;
                break;
        }
    }

    /**
     * 获得自己的状况
     *
     * @return 自己的状况
     */
    @Override
    public int getType() {
        return this.type;
    }

    /**
     * 获得妇女的请求
     *
     * @return 妇女的请求
     */
    @Override
    public String getRequest() {
        return this.request;
    }
}
package com.iot.practice.designpattern.chainofresponsibility.chainofresponsibilitypattern;

import com.iot.practice.designpattern.chainofresponsibility.IWomen;

/**
 * <p>Father 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 11:13</p>
 * <p>@remark:</p>
 */
public class Father extends Handler {

    /**
     * 父亲只处理女儿的请求
     */
    public Father() {
        super(1);
    }

    /**
     * 父亲的答复
     *
     * @param iWomen 女性统称
     */
    @Override
    public void response(IWomen iWomen) {
        System.out.println("--------女儿向父亲请示-------");
        System.out.println(iWomen.getRequest());
        System.out.println("父亲的答复是:同意\n");
    }
}
package com.iot.practice.designpattern.chainofresponsibility.chainofresponsibilitypattern;

import com.iot.practice.designpattern.chainofresponsibility.IWomen;

/**
 * <p>Husband 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 11:15</p>
 * <p>@remark:</p>
 */
public class Husband extends Handler {

    /**
     * 丈夫只处理妻子的请求
     */
    public Husband() {
        super(2);
    }

    /**
     * 丈夫的答复
     *
     * @param iWomen 女性统称
     */
    @Override
    public void response(IWomen iWomen) {
        System.out.println("--------妻子向丈夫请示-------");
        System.out.println(iWomen.getRequest());
        System.out.println("丈夫的答复是:同意\n");
    }
}
package com.iot.practice.designpattern.chainofresponsibility.chainofresponsibilitypattern;

import com.iot.practice.designpattern.chainofresponsibility.IWomen;

/**
 * <p>Son 此类用于:</p>
 * <p>@author:hujm</p>
 * <p>@date:2021年02月19日 11:18</p>
 * <p>@remark:</p>
 */
public class Son extends Handler {

    /**
     * 儿子只处理母亲的请求
     */
    public Son() {
        super(3);
    }

    /**
     * 儿子的答复
     *
     * @param iWomen 女性统称
     */
    @Override
    public void response(IWomen iWomen) {
        System.out.println("--------母亲向儿子请示-------");
        System.out.println(iWomen.getRequest());
        System.out.println("儿子的答复是:同意\n");
    }
}

 

 

 

end!

 

Guess you like

Origin blog.csdn.net/weixin_44299027/article/details/113885752