Software Design Pattern (3): Chain of Responsibility Pattern

Preface

        Previously, Litchi sorted out the relevant knowledge about singleton mode and strategy mode. In this article, Litchi will follow the previous writing method and experience this chain of responsibility design mode based on the example demo. I hope it will be helpful to friends in need, hahahahaha~ ~~


Article directory

Preface

chain of responsibility model 

1 simple scene 

2 Understanding the chain of responsibility model 

 3 doFilter in servlet package under Java

Summarize


chain of responsibility model 

        The chain of responsibility model connects a series of processing units through pointers and executes them in order to complete the processing of the request. When a processing unit in the chain of responsibility model is not suitable for processing the request, the request will continue to be passed to the next unit. It often uses a shared context object to wrap the request, which also contains the output model of the chain of responsibility. The process of sequential execution of the responsibility chain is the process of gradual improvement of the context output model.

1 simple scene 

In order to understand better, we first need to design the scenario to understand: Now we need to develop a filtering mechanism to prevent illegal input in the Msg object. The following code is a pattern that does not use the chain of responsibility. 

package com.crj.test;

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

public class SimpleMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("伪装一下注入:<script>关键词。。999......");

        List<Filter> filters = new ArrayList<>();
        filters.add(new HTMLFilter());
        filters.add(new SensitiveFilter());

        for(Filter f:filters){
            f.doFilter(msg);
        }

        System.out.println(msg);
    }
}

class Msg{
    String name;
    String msg;

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    @Override
    public String toString() {
        return "Msg{" +
                "name='" + name + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }

}

interface Filter{
    void doFilter(Msg m);
}

/**
 * HTML过滤
 */
class HTMLFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace('<','[');
        r = r.replace('>',']');
        m.setMsg(r);
    }
}
/**
 * 敏感词过滤
 */
class  SensitiveFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace("999","666");
        m.setMsg(r);
    }
}

2 Understanding the chain of responsibility model 

        Using the chain of responsibility pattern to write demos, you can see that we have added a class FilterChain, add different filtering rules through the add() method encapsulated in this class, and at the same time call the overridden doFilter declared by different rule objects. Method to implement filtering. This process is like a string of candied haws, each of which needs to be strung together with a bamboo stick. This bamboo stick is the FilterChain class, and the candied haws are different filtering rule classes.

package com.crj.test;

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

public class SimpleMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("伪装一下注入:<script>关键词。。999......");

        FilterChain fc = new FilterChain();
        fc.add(new HTMLFilter());
        fc.add(new SensitiveFilter());

        fc.doFilter(msg);

        System.out.println(msg);
    }
}

class Msg{
    String name;
    String msg;

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    @Override
    public String toString() {
        return "Msg{" +
                "name='" + name + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }

}

interface Filter{
    void doFilter(Msg m);
}

/**
 * HTML过滤
 */
class HTMLFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace('<','[');
        r = r.replace('>',']');
        m.setMsg(r);
    }
}
/**
 * 敏感词过滤
 */
class  SensitiveFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace("999","666");
        m.setMsg(r);
    }
}
/**
 * 过滤链
 */
class FilterChain{
    List<Filter> filters = new ArrayList<>();
    public void add(Filter filter){
        filters.add(filter);
    }
    public void doFilter(Msg m){
        for(Filter f:filters){
            f.doFilter(m);
        }
    }
}

 3 doFilter in servlet package under Java

        Java EEJDK provides a doFilter method under the servlet package to implement the chain of responsibility mode. There are three main specific parameters: request, response and FilterChain type chain. This method can filter requests and responses at the same time. That is, assuming a request comes in, the three filtering rules A, B, and C are filtered in the order of ABC. When the request is responded to, the Response sent will be filtered according to the rules of CBA. The implementation of this process is similar to a recursive algorithm. 

        We can use this diagram to understand the recursive process of responsibility chain calls in this method. After each request is hit on the filter class for processing, the doFilter() method will be called and the pointer will point to the next filter class to process the request. Next After a class is processed, execute the doFilter() method to check whether index == the length of the responsibility chain list. If so, it will return and fall back to the doFilter() method in the previous filter class to execute and return. 

According to the requirements, we need to encapsulate the Request and Response classes, define the Filter class and its corresponding implementation class, and the encapsulated FilterChain class implements the specific responsibility chain mode. The demo is as follows:

package com.crj.test2;

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

public class ServletChain {
    public static void main(String[] args) {
        Request request = new Request();
        request.str = "大家好999<script>";
        Response response = new Response();
        response.str = "response";

        FilterChain chain = new FilterChain();
        chain.add(new HTMLFilter()).add(new SensitiveFilter());
        chain.doFilter(request,response,chain);
    }
}

/**
 * 处理对象类
 */
class Request{
    String str;
}
class Response{
    String str;
}

/**
 * Filter接口
 */
interface Filter{
    boolean doFilter(Request request,Response response,FilterChain chain);
}

/**
 * 两个过滤类
 */
class HTMLFilter implements Filter{
    @Override
    public boolean doFilter(Request request, Response response,FilterChain chain) {
        request.str = request.str.replaceAll("<", "[").replaceAll(">", "]") + "HTMLFilter()";
        chain.doFilter(request, response, chain);
        response.str += "--HTMLFilter()";
        return true;
    }
}

class SensitiveFilter implements Filter{
    @Override
    public boolean doFilter(Request request, Response response,FilterChain chain) {
        request.str = request.str.replaceAll("996", "955") + " SensitiveFilter()";
        chain.doFilter(request, response, chain);
        response.str += "--SensitiveFilter()";
        return true;
    }
}

/**
 * 责任链实现类
 */
class FilterChain implements Filter{
    List<Filter> filters = new ArrayList<>();

    int index = 0;
    public FilterChain add(Filter f){
        filters.add(f);
        return this;
    }

    @Override
    public boolean doFilter(Request request, Response response,FilterChain chain) {
        if(index==filters.size()) return false;
        Filter f = filters.get(index);
        index++;
        return f.doFilter(request,response,chain);
    }
}

The article mainly uses cases provided in Teacher Ma’s course, link:

https://www.bilibili.com/video/BV1G44y1R7nv?p=14&vd_source=91c021af5a207c9fdf0bd7969d48cbf2


Summarize

        In this article, Lizhi mainly sorted out the concepts related to the chain of responsibility model in design patterns. Here, Lizhi did not give too many conceptual things but focused on the code scenario to understand haha. Litchi is a slow learner of design patterns and has been taking too many classes recently. Maybe the order of the articles is a little messy. Next, Litchi will continue to learn and produce~~~Let’s work hard on transcoding~

Today has become the past, but we still look forward to the future tomorrow! I am Xiaolizhi, and I will accompany you on the road of technological growth. Coding is not easy, so please raise your little paw and give me a thumbs up, hahaha~~~ Bixinxin♥~~~

Guess you like

Origin blog.csdn.net/qq_62706049/article/details/132724097