责任链设计模式
今天,我们来聊责任链设计模式。之前我们在玩观察者模式的时候,也有一点责任链设计模式的思想。
我们给每一个事件源添加的事件处理机制,在事件触发以后全部都会被执行。
在我们使用的各种框架上几乎都用到了责任链设计模式,例如Mybatis,spring等。后面我们细聊。
接下来我们先来聊一下责任链模式的原理。还是先来一个图
每一次请求都会经历一连串的拦截,只有通过了前面的拦截才能进入下一步。这个和我们经历的面试类似,像阿里的五轮面试,只有通过前面的面试才能进入下一个环节。
我们先来一个「简单版本的责任链模式」的代码实现。
- 过滤器
interface Filter{
void doFilter(Student student);
}
class TimerFilter implements Filter{
@Override
public void doFilter(Student student) {
student.setName(student.getName()+new Date().toString());
}
}
class Sensitive implements Filter {
@Override
public void doFilter(Student student) {
student.setName(student.getName()+"sensitive");
}
}
- 调用
public static void main(String[] args) {
Student student = new Student();
student.setName("木争");
List<Filter> filters = new ArrayList<>();
filters.add(new TimerFilter());
filters.add(new Sensitive());
for (Filter filter : filters) {
filter.doFilter(msg);
}
}
可以看到所有的过滤器均会被执行;这种方法的缺点是无法在中间停止。下面我们实现一个可以在中间暂停的过滤器链,思想很简单,就是将一个判断即可。
来看图
「可以中断的过滤器链」
- 过滤器
interface Filter{
boolean doFilter(Student student);
}
class TimerFilter implements Filter{
@Override
public boolean doFilter(Student student) {
student.setName(student.getName()+new Date().toString());
return true ;
}
}
class Sensitive implements Filter {
@Override
public boolean doFilter(Student student) {
student.setName(student.getName()+"sensitive");
return true ;
}
}
class LogFilter implements Filter {
@Override
public boolean doFilter(Student student) {
student.setName(student.getName()+"logFilter");
return false ;
}
}
- 过滤器链
class FilterChain implements Filter{
private List<Filter> filters = new ArrayList<>();
public FilterChain addFilter(Filter filter){
filters.add(filter);
return this ;
}
@Override
public boolean doFilter(Student student) {
for (Filter filter : filters) {
if(!filter.doFilter(student)) return false;
}
return true ;
}
}
- 调用
public static void main(String[] args) {
Student student = new Student();
student.setName("木争");
new FilterChain().addFilter(new TimerFilter())
.addFilter(new LogFilter())
.addFilter(new Sensitive()).doFilter(student);
System.out.println(student.getName());
}
这种方式可以在指定的过滤器进行中断操作,主要实现是通过一个定义一个过滤器链FilterChain,通过对调用具体的Filter做判断实现。
再来一个图:
接下来兄弟们回想一下我们再学习JavaWeb的时候JavaEE提供过一个Filter的组件,他可以让请求再执行前和之前后都经历这个过滤器。我们来看一下他的执行图
这个图就是一个完整的责任链模式的实现。我们来思考一下这样的效果如何实现,题刷的多的兄弟,应该可以看得出,这有点类似于一个递归的过程。思路有了,接下来看一下实现。
- 过滤器
interface Filter{
void doFilter(Request request , Response response , FilterChain filterChain);
}
class LogFilter implements Filter{
public void doFilter(Request request, Response response, FilterChain filterChain) {
System.out.println("处理Request请求========LogFilter");
filterChain.doFilter(request,response);
System.out.println("处理Response请求========LogFilter");
}
}
class TimerFilter implements Filter{
@Override
public void doFilter(Request request, Response response, FilterChain filterChain) {
System.out.println("处理Request请求========TimerFilter");
filterChain.doFilter(request,response);
System.out.println("处理Response请求========TimerFilter");
}
}
- 过滤器链
interface FilterChain{
void doFilter(Request request , Response response);
}
class MyFilterChain implements FilterChain {
int index = 0 ;
List<Filter> filters = new ArrayList<>();
public MyFilterChain addFilter(Filter filter){
filters.add(filter);
return this ;
}
@Override
public void doFilter(Request request, Response response) {
if(index == filters.size()){
return ;
}
Filter filter = filters.get(index);
index++;
filter.doFilter(request,response,this);
}
}
- 执行过程
public static void main(String[] args) {
MyFilterChain filterChain = new MyFilterChain().addFilter(new LogFilter()).addFilter(new TimerFilter());
Request request = new Request();
Response response = new Response();
filterChain.doFilter(request,response);
}
其实这个设计与上一个的区别就是在过滤器传参的时候传入了一个执行链,这样将执行权交给了过滤器本身,过滤器自己可以决定是否想要继续执行。而在执行完所有的过滤器以后,调用的过滤器链的方法递归调用,形成
A--->B--->C---->C---->B---->A的情况。
来一个图搞明白
责任链模式到此结束,我们来简单总结一下,我们拿过滤器为例,最完整的一个过滤器的构成是由过滤器和过滤器链,过滤器自己调用过滤器链执行剩余的过滤器,如果过滤器不想执行,直接返回即可,不需要调用过滤器链即可。好啦,结束。over!!!兄弟们单身快乐,冲冲冲!!!
本文使用 mdnice 排版