一、什么是责任链模式
1.先看看百度百科是怎么解释的
责任链模式是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
——百度百科
我们可以理解到,责任链就是多个对象一起共同对一个请求进行处理,这里还提到的,直到链上的某一个对象决定处理此请求。如果只是有一个对象对请求进行处理的话,那为什么要话费这么大的力气去组成这一条责任链呢?这不是多此一举吗?
2.我对责任链的看法
首先,责任链的这个设计模式,肯定是将一个请求分散给多个对象处理,为了更加的直观方便,于是将处理对象串成一条链条,让它们一直调用下家来进行处理这个请求。
其次,责任链并不是只有一个对象决定对请求进行处理,而是全部对象共同对这个请求进行处理,只是分别在不同的维度上而已。
简单地画个图作为对责任链的描述
3.使用责任链的优缺点
优点
- 让每个类更加地专注自己的责任。
- 使编码过程更加的清晰。
- 降低耦合度。降低了代码的复杂度
- 新增或修改更加方便
缺点
- 处理存在延迟
- 不能保证请求一定被处理
- 责任链较长会影响系统性能
- 进行代码调试时不方便
二、增强型责任链(过滤器)
因为感觉跟增强型代理特别像,就比较大胆地将名字取成了增强型责任链,它也可以叫过滤器。
1.特点
- 最终处理对象不变
- 使用习惯不变
- 业务无关性
- 附加新功能
- 请求一定会被处理
总的来说,增强型责任链的处理对象仍然是只有一个,很符合百度百科的解释,就是整一条责任链中,只有最后一个对象才会对请求进行处理,其他的都是在作一些记录,或者是上锁,都是一切无关业务的操作。增强型责任链更加侧重的点是无关业务逻辑的操作。
2.常见的例子
- tomcat中的Filter接口,在请求的时候采用了这种增强型责任链,最终处理请求的对象没有改变,它是一层一层地将request和response传递给servlet对象处理的。
- struts2中也存在过滤器,具体用来干嘛的,我也想不起来了,好像是用来校验的。
三、拦截器责任链
1.特点
- 最终处理对象不变
- 使用习惯不变
- 改变业务逻辑
- 请求不一定被处理
总的来说,拦截器责任链会影响到业务的逻辑,一旦其中的一个对象验证时不符合条件,就会中断整个请求,就像是一系列的if包裹在一起。拦截器责任链更加侧重的点是业务逻辑。
2.常见的例子
- HandlerInterceptorAdapter类
- 同样是struts2里面也有拦截器,可以用作拦截用户无登陆进入网站。
- spring中也有拦截器
四、过程型责任链(pipeline责任链)
1.特点
- 处理对象不单一
- 责任链对象顺序有要求
- 使用更加方便
- 业务无关性
- 请求一定会被处理
总的来说,过程型责任链就是将一个请求分给多个对象进行处理,处理的顺序有些会存在严格要求,当全部对象都进行了处理之后就会返回。有点像链接型代理,对多个方法进行了封装,但是过程型责任链对处理的顺序有要求。过程型责任链更加侧重的点是处理的过程。
2.常见的例子
- Jenkins打包工具,它就是将源代码处理成字节码,再打包成wai包,然后发布。
五、总结
增强型责任链更加侧重的点是无关业务逻辑的操作。
拦截器责任链更加侧重的点是业务逻辑。
过程型责任链更加侧重的点是处理的过程。
这三个责任链分别从三个维度出发,形成了各有特色的责任链。
不排除以后会出现更多的责任链,但是它们的本质都是从不同维度对一个请求进行处理,它们的形式都是一个链条。
六、责任链简单的实现方式
这是仿照tomcat里的过滤器责任链来实现的,想要实现其他的责任链,做出一些修改即可。
- 先创建一个Filter接口,作为责任链中存放对象的原型
package responsibilitychain;
/**
* @author xxj
* 过滤器
*/
public interface Filter {
/**
* 责任链中最终执行的方法
* @param object 传递的需要处理的对象
* @return 改成boolean的话就是拦截器了,
*/
void doFilter(Object object);
}
- 创建一个FilterChain类,作为责任链管理器
package responsibilitychain;
import java.util.ArrayList;
import java.util.List;
/**
* @author xxj
* 责任链管理器
*/
public class FilterChain implements Filter {
List<Filter> list =new ArrayList<>();
public void addFilter(Filter filter){
list.add(filter);
}
@Override
public void doFilter(Object object) {
list.forEach(f -> f.doFilter(object));
}
}
- 使用责任链
每个责任链对象都需要单独创建一个类,这个类需要实现Filter接口
package responsibilitychain;
/**
* @author xxj
* 测试责任链
* 对一个String对象进行修改
*/
public class test {
public static void main(String[] args){
//创建责任链管理器
FilterChain filterChain=new FilterChain();
//添加责任链
filterChain.addFilter(new FirstFilter());
filterChain.addFilter(new SecondFilter());
filterChain.addFilter(new LastFilter());
//调用责任链
String string=" aaa ";
filterChain.doFilter(string);
}
static class FirstFilter implements Filter{
@Override
public void doFilter(Object object) {
//强转成String
String string=(String)object;
//输出String的长度
System.out.println(string.length());
}
}
static class SecondFilter implements Filter{
@Override
public void doFilter(Object object) {
//强转成String
String string=(String)object;
//去掉空格
string=string.trim();
//再输出长度
System.out.println(string.length());
}
}
static class LastFilter implements Filter{
@Override
public void doFilter(Object object) {
//强转成String
String string=(String)object;
//输出string
System.out.println(string);
}
}
}
- 输出的结果
10
3
aaa
——————————————————————————————
如果本文章内容有问题,请直接评论或者私信我。
未经允许,不得转载!