作者:Grey
原文地址:
责任链模式是一种行为型模式。
举例说明:有一段文本需要过滤一系列敏感字,我们可以通过责任链模式来设计这个功能,假设文本是
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 图如下
责任链模式应用
Java 中的 Servlet filter;
Structs,Spring MVC 中的 interceptor;
Dubbo 中的 Filter;
Netty 中的 ChannelPipeline。