责任链模式(Chain of Responsibility) : 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
应用场景
-
一个请求需要一系列的处理工作,可以避免避免大段的if else语句。(tomcat的Filter;mybatis的Interceptor)
-
对系统进行扩展补充。
代码实现
模拟一个请求对字符拆串的处理,这个时候我们一般都会想到直接在代码里使用if-else判断特殊字符进行处理(替换数字1和2),类似于
String msg = "ab_1_ab_2";
if ("1".equals(msg)) {
// do something
} else if ("2".equals(msg)) {
// do something
}
看起来确实没有什么问题,但是如果我们不是处理简单的字符串,而是一些复杂的业务逻辑,那逻辑处理do something
的代码量就非常复杂且庞大。并且业务逻辑需要扩展的时候就要重新修改if-else判断,非常不利程序的维护、扩展。这时候责任链模就可以大展身手了。代码如下(类似tomcat的Filter,只不过这里只处理单向的责任链)
定义一个Filter接口和消息实体
public interface Filter {
abstract void doFilter(Msg msg);
}
//消息实体
@Data
@Accessors(chain = true)
public class Msg {
String msg;
}
责任链管理类FilterChain
这里也实现了Filter,主要是为了在定义多个FilterChain的时候,能够使用addfilter将两条链合并为一条链。有个地方注意,doFilter方法返回void,则会执行list里面的所有filter。如果不想要执行所有filter,可以定义boolean的doFilter方法,这里不做讨论。
public class FilterChain implements Filter {
//存放所有自定义Filter
private List<Filter> list = new ArrayList<>();
//添加自定义的Filter到list
public FilterChain addfilter(Filter filter) {
list.add(filter);
return this;
}
//遍历执行所有自定义的Filter
@Override
public void doFilter(Msg msg) {
for (Filter filter : list){
filter.doFilter(msg);
}
}
/*public boolean doFilter(Msg msg) {
for (Filter filter : list){
if (!filter.doFilter(msg)) return false;
}
return true;
}*/
}
Filter实现类
public class OneFilter implements Filter {
@Override
public void doFilter(Msg msg) {
msg.setMsg(msg.getMsg().replace("1", "one"));
}
}
public class TwoFilter implements Filter {
@Override
public void doFilter(Msg msg) {
msg.setMsg(msg.getMsg().replace("2", "Two"));
}
}
测试类
输出结果为ab_one_ab_Two
public static void main(String[] args) {
Msg msg=new Msg().setMsg("ab_1_ab_2");
FilterChain chain = new FilterChain();
chain.addfilter(new OneFilter()).addfilter(new TwoFilter());
chain.doFilter(msg);
System.out.println(msg.getMsg());
}