设计模式-责任链模式

责任链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

每一个对象只会处理自己范围内的事情,过界就交给其他对象继续执行,整个过程逻辑上就形成了一个链。

        给出一个场景:当向数据库存储一条数据的时候Msg,对于Msg可能会有一些违规的信息,敏感词之类的,这个时候就要在实际存储到数据库前进行一些操作;常规的想法就是加一些过滤器 (学习Java最熟悉的应该就是Filter)

就这个样子

  • 最常规的写法
public class Main {

    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("大家好:<a href='xxx.com'> 我是xxx </a>, 限时998!(狗头");

        // 1.如何替换 <a> 代码,替换敏感词 998 和 狗头表情
        String message = msg.getMsg();
        message = message.replace('<', '[');
        message = message.replace('>', ']');
        message = message.replace("998", "998元");
        message = message.replace("狗头", "禁止狗头保命");
        msg.setMsg(message);

        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{" +
                "msg='" + msg + '\'' +
                '}';
    }
}

        类似的,可以将不同的处理逻辑单独进行封装:

class HTMLFilter implements Filter {

    @Override
    public Filter doFilter(Msg msg) {
        String message = msg.getMsg();
        msg.setMsg(message.replace('<', '[').replace('>', ']'));
        return this;
    }
}

class SensitiveFilter implements Filter {

    @Override
    public Filter doFilter(Msg msg) {
        msg.setMsg(msg.getMsg().replace("998", "998元"));
        return this;
    }
}

class DogFaceFilter implements Filter {


    @Override
    public Filter doFilter(Msg msg) {
        msg.setMsg(msg.getMsg().replace("狗头", "禁止狗头保命"));
        return this;
    }
}

        简单的写法就是全写在主程序中,很明显代码耦合太强,不易扩展;如果处理逻辑复杂,代码会很复杂,如果有其他过滤条件,需要更改源程序。

        解决方案:由一个对象统一处理,作为统一入口 -》 可以考虑集合

public static void main(String[] args) {
	Msg msg = new Msg();
	msg.setMsg("大家好:<a href='xxx.com'> 我是xxx </a>, 限时998!(狗头");

	// 统一管理过滤器
	List<Filter> chains = new ArrayList<>();
	chains.add(new HTMLFilter());
	chains.add(new SensitiveFilter());
	chains.add(new DogFaceFilter());
	for (Filter filter : chains) {
		filter.doFilter(msg);
	}

	System.out.println(msg);
}

        将所有需要的过滤器统一保存,然后顺次执行。

  • FilterChain

进一步的,如何将集合中的Filter构造成链?  虽说是链,也只是一种逻辑概念,一种顺次执行吧(自己理解)

class FilterChain {
    List<Filter> chains = new ArrayList<>();

    public FilterChain add(Filter filter) {
        chains.add(filter);
        return this;   // 链式编程
    }

    public void doFilter(Msg msg) {
        for (Filter filter : chains) {
            filter.doFilter(msg);
        }
    }
}

这里的 return this 是一种编程写法,这样可以在调用的时候链式编程

chain.add(new HTMLFilter()).add(new DogFaceFilter());

JavaWeb中Servlet对于Filter的实现,如果处理Request和Response,并保证Request和Response的处理是相反的?

 在JavaEE中的实现是传入第三个参数FilterChain,然后利用递归的思想进行调用

1. 自定义Request, Response

class Request {
    String str;
}

class Response {
    String str;
}

2. 赋予过滤器可以终止行为的功能,如果不满足添加可以直接return false,进行终止;并且整体过滤器的进行不在用for进行统一执行,而用Index控制

class HTMLFilter implements Filter {

    @Override
    public Filter doFilter(Request request, Response response, FilterChain chain) {

        request.str += "1";
        chain.doFilter(request, response);
        response.str += "1";
        return this;
    }
}

 这里HTMLFilter中执行的是 += “1”, 其他的依次 += “2”, += “3”就行了,就是为了显示效果。

3. 定义过滤器链

class FilterChain {
    List<Filter> chains = new ArrayList<>();
    int index = 0;

    public FilterChain add(Filter filter) {
        chains.add(filter);
        return this;
    }

    public void doFilter(Request request, Response response) {
        if (index == chains.size()) return;
        Filter filter = chains.get(index);  // 获取当前Filter
        index ++;
        filter.doFilter(request, response, this);  // 具体Filter的执行逻辑
    }
}

4. 主程序调用

public static void main(String[] args) {

	FilterChain chain = new FilterChain();
	chain.add(new HTMLFilter()).add(new SensitiveFilter()).add(new DogFaceFilter());
	Request request = new Request(); request.str = "request:";
	Response response = new Response(); response.str = "response:";
	chain.doFilter(request, response);

	System.out.println(request.str + " " + response.str);
}

5.运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值