设计模式(一)Chain Of Responsibility责任链模式

设计模式篇章,源于网课的学习,以及个人的整理

 

在我们接收用户提交的字符时,常常会使用到过滤,在学习责任链模式前,我们是这样做的

1.定义一个类

public class MsgProcesser {
    String msg;
    
    public MsgProcesser(String msg) {
        this.msg=msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    
    public String process() {
        String r=msg.replace("<", "[").replaceAll(">", "]");
        r=r.replaceAll("被就业", "就业");
        r=r.replaceAll("敏感", "");
        return r;
    }
}

测试

public static void main(String[] args) {
        String message="大家好:),<script>,敏感,被就业,网络授课没感觉,因为看不见大家伙儿";
        MsgProcesser mp=new MsgProcesser(message);
        System.out.println(mp.process());
    }

往往添加数据会很不方便,于是,借用责任链的方式,我们可以这样写

 1.定义一个接口,内部有抽象方法doFilter

package com.littlepage.testChainOfResponsibility;

public interface Filter {
    String doFilter(String str);
}

2.定义一些不同的过滤器类实现过滤器接口,类似HTMLFilter,SensitiveFilter

package com.littlepage.testChainOfResponsibility;

public class HTMLFilter implements Filter{

    @Override
    public String doFilter(String str) {
        return str.replaceAll("<", "[").replaceAll(">", "]");    
    }

}
package com.littlepage.testChainOfResponsibility;

public class SensitiveFilter implements Filter{

    @Override
    public String doFilter(String str) {
        return str.replaceAll("敏感", "*");
    }
    
}

3.进行主要链条的编写,就是新建一个类叫MsgProcesser,该类将这些方法进行串起来,使用foreach循环进行迭代进行过滤,在后续情况下,也就是说,你需要再添加过滤的关键字,就可以直接新建一个链条上的小块(也就是一个类),进行添加,而不用再去写其他东西

package com.littlepage.testChainOfResponsibility;

public class MsgProcesser {
    Filter[] filter= {new HTMLFilter(),new SensitiveFilter()};
    String msg;
    
    public MsgProcesser(String msg) {
        this.msg=msg;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    
    public String process() {
        String r=msg;
        for(Filter f:filter) {
            r=f.doFilter(r);
        }
        return r;
    }
}

图示:

或者说,你依然可以定义一个责任链类(FilterChain)用来代替MsgProcesser类,里面用ArrayList容器盛放filter

该代码为:

package com.littlepage.testChainOfResponsibility;

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

public class FilterChain {
    List<Filter> filters=new ArrayList<>();
    public FilterChain addFilter(Filter f) {
        filters.add(f);
        return this;
    }
    public String doFilter(String str) {
        String r=str;
        for (Filter filter : filters) {
            r=filter.doFilter(r);
        }
        return r;
    }
}

主方法的调用改为

package com.littlepage.testChainOfResponsibility;

public class Main {
    public static void main(String[] args) {
        String message="大家好:),<script>,敏感,被就业,网络授课没感觉,因为看不见大家伙儿";
        FilterChain fc=new FilterChain();
        fc.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());
        System.out.println(fc.doFilter(message));
        
    }
}

若该FilterChain也实现Filter接口,那么就可以自己添加自己的FilterChain了,很巧妙

由此可以拓展出,tomcat下可以加上request和response过滤器

代码如下:

 

package top.littlepage.designPattern.responsibilityChain;

public interface Filter {
    void doFilter(Request req,Response res,FilterChain fc);
}
package top.littlepage.designPattern.responsibilityChain;

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

public class FilterChain implements Filter {
    List<Filter> filters = new ArrayList<>();
    int index = -1;

    public FilterChain addFilter(Filter f) {
        filters.add(f);
        return this;
    }

    public void doFilter(Request req, Response res, FilterChain fc) {
        if (index == filters.size()-1)
            return;
        index++;
        filters.get(index).doFilter(req, res, fc);
        
    }

}
package top.littlepage.designPattern.responsibilityChain;

public class HTTPFilter implements Filter{

    @Override
    public void doFilter(Request req, Response res,FilterChain fc) {
        req.setRequestStr(req.getRequestStr().replaceAll("<", "[").replaceAll(">", "]"));
        System.out.println("after reqHttp:"+req);
        fc.doFilter(req, res, fc);
        res.setResponseStr(res.getResponseStr().replaceAll("//", "pp"));
        System.out.println("after resHttp:"+res);
    }

}
package top.littlepage.designPattern.responsibilityChain;

public class Request {
    private String requestStr;

    public Request() {
        requestStr="";
    }

    public Request(String requestStr) {
        this.requestStr = requestStr;
    }

    public String getRequestStr() {
        return requestStr;
    }

    public void setRequestStr(String requestStr) {
        this.requestStr = requestStr;
    }

    @Override
    public String toString() {
        return "Request [requestStr=" + requestStr + "]";
    }
}
package top.littlepage.designPattern.responsibilityChain;

public class Response {
    private String responseStr;

    public Response() {
        responseStr="";
    }

    public Response(String responseStr) {
        this.responseStr = responseStr;
    }

    public String getResponseStr() {
        return responseStr;
    }

    public void setResponseStr(String responseStr) {
        this.responseStr = responseStr;
    }

    @Override
    public String toString() {
        return "Response [responseStr=" + responseStr + "]";
    }
    
}
package top.littlepage.designPattern.responsibilityChain;

public class SensitiveFilter implements Filter{

    @Override
    public void doFilter(Request req, Response res,FilterChain fc) {
        req.setRequestStr(req.getRequestStr().replaceAll("sensitive", "***"));
        System.out.println("after reqSen:"+req);
        fc.doFilter(req, res, fc);
        res.setResponseStr(res.getResponseStr().replaceAll("mingan", "notmingan"));
        System.out.println("after resSen:"+res);
    }
}
package top.littlepage.designPattern.responsibilityChain;

public class Test {
    public static void main(String[] args) {
        String str="<script>//abbbmingansensitive";
        Request req=new Request(str);
        Response res=new Response(str);
        FilterChain fc=new FilterChain();
        fc.addFilter(new HTTPFilter());
        fc.addFilter(new SensitiveFilter());
        fc.doFilter(req, res, fc);
    }
}

控制台打印如下

 

可以看出,首先接收端进行接收request分别执行Http进行过滤req,执行Sensitive进行过滤req

到达服务端,开始原路返回,先执行Sensitive过滤器进行过滤,然后执行Http过滤器进行过滤,

这一系列变成了一个链条,将各个过滤器穿在一起,也就成了所说的责任链设计模式。

由于是一步一步进行拦截,所以说,也可以称作拦截器模式

由此可见:原理和tomcat的filter的大致原理一样,先原线路进行依次对请求值进行过滤,然后

再对客户端的返回值进行过滤

 

posted @ 2018-11-06 11:59  SteveYu  阅读(310)  评论(0编辑  收藏  举报