栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【设计模式】通过java过滤器理解责任链模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【设计模式】通过java过滤器理解责任链模式

如图所示,消息在进入数据库之前,会进过多层过滤器,我们可以在过滤器中对消息进行数据处理或者拦截。而这每一个Filter都有自己的责任,串成了一个链条就是责任链。数据按照顺序一层层经过这些过滤器。
直接上代码
简单说一下需求:有一个消息经过filter1,filter2. filter1和filter2都为该消息添加一些自己的字符串。

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

public class FilterMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("hello world");
		// 通过集合存储,将过滤器组合成一条责任链
        List filters = new ArrayList<>();
        filters.add(new Filter1());
        filters.add(new Filter2());

        for (Filter f : filters) {
            f.doFilter(msg);
        }
        System.out.println(msg); // hello world--经过filter1--经过filter2
    }
}

class Msg{
    private String msg;

    public String getMsg() {
        return msg;
    }

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

    @Override
    public String toString() {
        return msg;
    }
}

interface Filter{
    void doFilter(Msg m);
}

class Filter1 implements Filter{
    @Override
    public void doFilter(Msg m) {
        m.setMsg(m.getMsg()+"--filter1");
    }
}

class Filter2 implements Filter{
    @Override
    public void doFilter(Msg m) {
        m.setMsg(m.getMsg()+"--filter2");
    }
}

然后我们可以将Main方法中的

       // 通过集合存储,将过滤器组合成一条责任链
        List filters = new ArrayList<>();
        filters.add(new Filter1());
        filters.add(new Filter2());

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

抽离出来封装成一个FilterChain具体代码如下

import java.util.ArrayList;
import java.util.List;
//使用FilterChain
public class FilterMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("hello world");
        FilterChain fc = new FilterChain();
        fc.add(new Filter1())
          .add(new Filter2());
        fc.doFilter(msg);
        System.out.println(msg);
    }
}

class Msg{
    private String msg;

    public String getMsg() {
        return msg;
    }

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

    @Override
    public String toString() {
        return msg;
    }
}

interface Filter{
    void doFilter(Msg m);
}

class Filter1 implements Filter{
    @Override
    public void doFilter(Msg m) {
        m.setMsg(m.getMsg()+"--filter1");
    }
}

class Filter2 implements Filter{
    @Override
    public void doFilter(Msg m) {
        m.setMsg(m.getMsg()+"--filter2");
    }
}

class FilterChain implements Filter{
    List filters = new ArrayList<>();
    public FilterChain add(Filter f){
        filters.add(f);
        return this;
    }
    public void doFilter(Msg m){
        for (Filter f : filters) {
            f.doFilter(m);
        }
    }
}

当然有时候我们并不需要,消息经过整个责任链,有可能在第一个过滤器就因为数据不符合直接返回了。这种情况该如何实现呢?
我们需要修改一下Filter的doFilter,void->boolean
具体代码如下

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

public class FilterMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("hello world");

        FilterChain fc = new FilterChain();
        fc.add(new Filter1()).add(new Filter2());
        fc.doFilter(msg);
        System.out.println(msg);
    }
}

class Msg{
    private String msg;

    public String getMsg() {
        return msg;
    }

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

    @Override
    public String toString() {
        return msg;
    }
}

interface Filter{
    boolean doFilter(Msg m);
}

class Filter1 implements Filter{
    @Override
    public boolean doFilter(Msg m) {
        m.setMsg(m.getMsg()+"--filter1");
        return true;
    }
}

class Filter2 implements Filter{
    @Override
    public boolean doFilter(Msg m) {
        m.setMsg(m.getMsg()+"--filter2");
        return false;
    }
}

class FilterChain implements Filter{
    List filters = new ArrayList<>();
    public FilterChain add(Filter f){
        filters.add(f);
        return this;
    }

    public boolean doFilter(Msg m){
        for (Filter f : filters) {
            if(!f.doFilter(m)){  // 重点:判断只要有一个doFilter返回false就直接return false,不在继续执行下面的Filter
                return false;
            }
        }
        return true;
    }

}

最后是模拟Servlet的Filter的实现:
首先需要了解一下java中的Filter帮我们做了哪些事。
首先是request进来会经过Filter1,Filter2,Filter3然后进入到Servlet。而Servlet返回的时候会经过Filter3,FIlter2,Filter1,最终返回给客户端。这里很关键的一件事是,我们只写了一个过滤器链,确能够以123的顺序对request进行过滤,以321的顺序对response进行过滤。这是如何做到的呢?

直接上代码

package com.zxh.design.filter;

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



public class ServletFilterMain {

    public static void main(String[] args) {
        Request request = new Request();
        request.str = "request";
        Response response = new Response();
        response.str = "response";

        FilterChain chain = new FilterChain();
        chain.add(new Filter1())
             .add(new Filter2())
             .add(new Filter3());
        chain.doFilter(request,response);
        System.out.println(request.str);  // request--Filter1--Filter2--Filter3
        System.out.println(response.str);  // response--Filter3--Filter2--Filter1
    }

}

interface Filter{
    void doFilter(Request request,Response response,FilterChain filterChain);
}

class Request{
    String str;
}

class Response{
    String str;
}

class Filter1 implements Filter{
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
         request.str = request.str+"--Filter1";
         // 这里进行一个递归调用,为了保证request是正序,response是倒叙。
         // 对request的处理要放在chain.doFilter之前,对response的处理要放在之后
         chain.doFilter(request,response);
         response.str += "--Filter1"; // chain.doFilter执行结束后,response才有值,如果要对返回值进行处理需要在这里进行
    }
}

class Filter2 implements Filter{
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        request.str += "--Filter2";
        chain.doFilter(request,response);
        response.str += "--Filter2";
    }
}

class Filter3 implements Filter{
    @Override
    public void doFilter(Request request, Response response, FilterChain chain) {
        request.str += "--Filter3";
        chain.doFilter(request,response);
        response.str += "--Filter3";
    }
}

// 该类封装了过滤器链由doFilter方法进控制调用
class FilterChain{
    List filters = new ArrayList<>();
    int index = 0;

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

    public void doFilter(Request request,Response response){
        if(index == filters.size()) return;
        Filter filter = filters.get(index);
        index++;
        filter.doFilter(request,response,this);
    }
}

在Filter接口的doFilter的中新增了FilterChain 参数取消了返回值。我们将过滤器链的调用全部交给FilterChain。当我们调用chain.doFilter(request,response);该方法就会帮我们调用当前Filter,并且index++将下标指向下一个Filter.

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/704095.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号