设计模式学习(十六):责任链模式

设计模式,学习,十六,责任,模式 · 浏览次数 : 157

小编点评

**责任链模式**是一种行为型模式,它通过一系列步骤将请求处理到不同的对象上,最终将结果返回给请求方。 **设计模式学习(十六):责任链模式** **1. 责任链的定义** 责任链是一个单一接口,它包含一个或多个过滤器的方法。每个过滤器都实现特定的过滤逻辑,并将结果传递给下一个过滤器。 **2. 责任链的实现** * 创建一个抽象过滤器接口,定义其 `doFilter()` 方法。 * 创建实现特定过滤逻辑的具体过滤器实现类。 * 在主方法中,创建并链接多个过滤器。 * 对请求进行过滤时,逐个调用每个过滤器的方法。 * 返回`false`,如果任何过滤器拒绝处理请求,则整个过滤过程停止。 * 返回`true`,如果所有过滤器都处理了请求,则请求成功处理。 **3. 优点** * **可扩展性:**责任链可以轻松添加新的过滤器,以满足需求的改变。 * **透明性:**请求处理过程显而易懂,便于调试。 * **可维护性:**代码易于维护,因为每个过滤器只负责处理特定的逻辑。 **4. 缺点** * **性能:**责任链模式可能导致性能下降,因为每个请求需要遍历所有过滤器。 * **复杂性:**设置和维护责任链可能很复杂,特别是对于大型项目。 **5. 常见场景** * 过滤敏感数据,例如用户名、密码等。 * 处理异步请求。 * 将请求分发到多个服务器。 **6. 示例** ```java public class FilterChain implements Filter { private List filters; public FilterChain(List filters) { this.filters = filters; } @Override public boolean doFilter(Msg msg) { for (Filter filter : filters) { if (!filter.doFilter(msg)) { return false; } } return true; } } ``` **总结** 责任链模式是一种易于维护的过滤器设计模式,它可以用于各种应用场景。但是,它的性能可能受到一些影响,因此在某些情况下,可以使用其他模式,例如拦截器模式或过滤器链模式。

正文

设计模式学习(十六):责任链模式

作者:Grey

原文地址:

博客园:设计模式学习(十六):责任链模式

CSDN:设计模式学习(十六):责任链模式

责任链模式

责任链模式是一种行为型模式。

举例说明:有一段文本需要过滤一系列敏感字,我们可以通过责任链模式来设计这个功能,假设文本是

scripts Hell World! 996

我们有多个过滤规则,比如第一个规则是:过滤 scripts 这个关键字(实际的规则可能很复杂,目前只是举这个简单例子来说明情况)
第二个规则是:过滤 996 这个关键字

首先,将这个文本封装成一个 Msg 类,文本内容存在 content 变量中

public class Msg {
    private String content;

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

然后,可以抽象一个 Filter 接口,各种过滤规则无非就是实现这个接口即可

public interface Filter {
    boolean doFilter(Msg msg);
}

过滤掉 996 这个关键字的规则:

public class SensitiveFilter implements Filter {
    @Override
    public boolean doFilter(Msg msg) {
        msg.setContent(msg.getContent().replace("996", ""));
        return true;
    }
}

过滤 scripts 的规则:

public class HTMLFilter implements Filter {
    @Override
    public boolean doFilter(Msg msg) {
        msg.setContent(msg.getContent().replace("scripts", ""));
        return true;
    }
}

主方法调用的时候,就直接 New 相应的 Filter 来处理即可:

Msg msg=new Msg();
msg.setContent("scripts Hell World! 996");
System.out.println("before filter , the content is : "+msg.getContent());
Filter html=new HTMLFilter();
Filter sensitive=new SensitiveFilter();
html.doFilter(msg);
sensitive.doFilter(msg);
System.out.println("after filter , the content is : "+msg.getContent());

不过,更为优雅的一种方式是设计一个 FilterChain ,把所有的 Filter 都加入到这个 FilterChain 里面,对于 Msg 直接去调用 FilterChain 的过滤方法即可把 FilterChain 中的所有 Filter 都执行,而且还可以很灵活指定 Filter 顺序。

import java.util.*;
public class FilterChain implements Filter {
    private List<Filter> filters = new ArrayList<>();

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

    @Override
    public boolean doFilter(Msg msg) {
        for (Filter filter : filters) {
            if (!filter.doFilter(msg)) {
                return false;
            }
        }
        return true;
    }
}

那么主方法在调用的时候,可以直接通过如下的方式:

public class Main {
    public static void main(String[] args) {
        FilterChain filterChain = new FilterChain();
        filterChain.addFilter(new HTMLFilter()).addFilter(new SensitiveFilter());
        Msg msg = new Msg();
        msg.setContent("scripts Hell World! 996");
        System.out.println("before filter , the content is : " + msg.getContent());
        filterChain.doFilter(msg);
        System.out.println("after filter , the content is : " + msg.getContent());
    }
}

上述示例的 UML 图如下

image

责任链模式应用

  • Java 中的 Servlet filter;

  • Structs,Spring MVC 中的 interceptor;

  • Dubbo 中的 Filter;

  • Netty 中的 ChannelPipeline。

UML 和 代码

UML 图

代码

更多

设计模式学习专栏

参考资料

与设计模式学习(十六):责任链模式相似的内容:

设计模式学习(十六):责任链模式

设计模式学习(十六):责任链模式 作者:Grey 原文地址: 博客园:设计模式学习(十六):责任链模式 CSDN:设计模式学习(十六):责任链模式 责任链模式 责任链模式是一种行为型模式。 举例说明:有一段文本需要过滤一系列敏感字,我们可以通过责任链模式来设计这个功能,假设文本是 scripts H

设计模式学习(十):门面模式

设计模式学习(十):门面模式 作者:Grey 原文地址: 博客园:设计模式学习(十):门面模式 CSDN:设计模式学习(十):门面模式 门面模式 门面模式是一种结构型模式。 门面模式为子系统提供一组统一的接口,定义一组高层接口让子系统更易用。 假设建造一个房子需要有如下三个步骤: 第一步,和泥 第二

设计模式学习(十一):组合模式

设计模式学习(十一):组合模式 作者:Grey 原文地址: 博客园:设计模式学习(十一):组合模式 CSDN:设计模式学习(十一):组合模式 组合模式 组合模式是一种结构型模式。 组合模式中,最常用的一个用法就是目录层级的遍历,话不多说,直接上代码,主方法中 public class Main {

设计模式学习(十二):享元模式

设计模式学习(十二):享元模式 作者:Grey 原文地址: 博客园:设计模式学习(十二):享元模式 CSDN:设计模式学习(十二):享元模式 享元模式 享元模式是一种结构型模式。 一个应用场景是:运用共享技术有效地支持大量细粒度的对象。主要解决 在有大量对象时,有可能会造成内存溢出,我们把其中共同的

设计模式学习(十三):观察者模式

设计模式学习(十三):观察者模式 作者:Grey 原文地址: 博客园:设计模式学习(十三):观察者模式 CSDN:设计模式学习(十三):观察者模式 观察者模式 观察者模式是一种行为型模式。在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。 一般可以用做事件处理

设计模式学习(十四):模板方法

设计模式学习(十四):模板方法 作者:Grey 原文地址: 博客园:设计模式学习(十四):模板方法 CSDN:设计模式学习(十四):模板方法 模板方法 模板方法是一种行为型模式。 假设我们要实现一个游戏,这个游戏有「初始化」,「启动」,「结束」三个方法,那么可以定义一个游戏的模板: public a

设计模式学习(十五):策略模式

设计模式学习(十五):策略模式 作者:Grey 原文地址: 博客园:设计模式学习(十五):策略模式 CSDN:设计模式学习(十五):策略模式 策略模式 策略模式是一种行为型模式,它定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换。 以实例来说明 假设我们有一个猫类,这个类里面有体重和身高

设计模式学习(十七):状态模式

设计模式学习(十七):状态模式 作者:Grey 原文地址: 博客园:设计模式学习(十七):状态模式 CSDN:设计模式学习(十七):状态模式 状态模式 状态模式是一种行为型模式。 对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。 举例说明: Person 有 Cry ,

设计模式学习(十八):迭代器模式

设计模式学习(十八):迭代器模式 作者:Grey 原文地址: 博客园:设计模式学习(十八):迭代器模式 CSDN:设计模式学习(十八):迭代器模式 迭代器模式 迭代器模式是一种行为型模式。 迭代器最典型的应用是容器遍历 模仿 JDK 的容器,我们自定义一个容器并实现 iterator 方法; 首先,

设计模式学习(十九):访问者模式

设计模式学习(十九):访问者模式 作者:Grey 原文地址: 博客园:设计模式学习(十九):访问者模式 CSDN:设计模式学习(十九):访问者模式 访问者模式 访问者模式是一种行为型模式。 访问者模式在结构不变的情况下动态改变对于内部元素的动作。 举例说明: 假设我们需要构造一台电脑,有主板( Bo