一、责任链模式
一句话总结:比如一个web请求,有一堆的过滤器需要处理(或不处理)这个请求,而这一堆接收此次请求的过滤器对象形成一条调用链,即为责任链模式
- 定义:
为请求创建一个接收此次请求对象的链
- 类型:行为型
- 适用场景:一个请求的处理需要多个对象当中的一个或几个协作处理
- 优点:
- 请求的发送者和接收者(请求的处理)解耦
- 责任链可以动态组合
- 缺点:
- 责任链太长或者处理时间过长,影响性能
- 责任链有可能过多
- 相关设计模式
- 责任链模式和
状态模式
:责任链模式当中各个对象并不指定下一个处理的对象者是谁,只有在客户端来设定链条中的顺序以及元素
,直到被某个元素处理,或者整个链条结束,状态模式是让每个状态模式知道自己下一个处理的对象是谁
,也就是说在编译时就设定好了,这个是他俩最大的区别。
二、Coding
public class Course {
private String name;
private String article;
private String video;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getArticle() {
return article;
}
public void setArticle(String article) {
this.article = article;
}
public String getVideo() {
return video;
}
public void setVideo(String video) {
this.video = video;
}
@Override
public String toString() {
return "Course{" +
"name='" + name + '\'' +
", article='" + article + '\'' +
", video='" + video + '\'' +
'}';
}
}
public abstract class Approver {
protected Approver approver;
public void setNextApprover(Approver approver) {
this.approver = approver;
}
public abstract void deploy(Course course);
}
public class ArticleApprover extends Approver {
@Override
public void deploy(Course course) {
if (course.getArticle() != null) {
System.out.println(course.getName() + "含有手记,批准");
if (approver != null) {
approver.deploy(course);
}
} else {
System.out.println(course.getName() + "不含有手记,不批准,流程结束");
}
}
}
public class VideoApprover extends Approver {
@Override
public void deploy(Course course) {
if (course.getVideo() != null) {
System.out.println(course.getName() + "含有视频,批准");
if (approver != null) {
approver.deploy(course);
}
} else {
System.out.println(course.getName() + "不含有视频,不批准,流程结束");
}
}
}
public class Test {
public static void main(String[] args) {
Approver articleApprover = new ArticleApprover();
Approver videoApprover = new VideoApprover();
Course course = new Course();
course.setName("Java设计模式");
course.setArticle("Java设计模式的手记");
course.setVideo("Java设计模式的视频");
articleApprover.setNextApprover(videoApprover);
articleApprover.deploy(course);
}
}
Java设计模式含有手记,批准
Java设计模式含有视频,批准
// 将 course.setVideo("Java设计模式的视频"); 注释后,打印结果:
Java设计模式含有手记,批准
Java设计模式不含有视频,不批准,流程结束
- UML类图:
![责任链模式UML](https://img-blog.csdnimg.cn/20210321105639336.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MjIxNzg4,size_16,color_FFFFFF,t_70)
- 说明:其实类图也很简单,两个
Approver
类继承了其抽象类,Course
是课程主题,最重要的方法就是抽象类 Approver
,责任链的核心就是 Approver
类里面包含一个自己同样类型的对象,一般设为 protected
,用于子类继承。
三、源码中的应用
- javax.servlet.Filter:重点看它的doFilter方法,看看它有个传参FilterChain,随便找一个它下面的实现类MockFilterChain,可以看到它的doFilter方法里面调用了下一个Filter的doFilter方法。
public interface Filter {
void init(FilterConfig var1) throws ServletException;
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;
void destroy();
}
public interface FilterChain {
void doFilter(ServletRequest var1, ServletResponse var2) throws IOException, ServletException;
}
public class MockFilterChain implements FilterChain {
private final List<Filter> filters;
...
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
if (this.request != null) {
throw new IllegalStateException("This FilterChain has already been called!");
} else {
if (this.iterator == null) {
this.iterator = this.filters.iterator();
}
if (this.iterator.hasNext()) {
Filter nextFilter = (Filter)this.iterator.next();
nextFilter.doFilter(request, response, this);
}
this.request = request;
this.response = response;
}
}
...
}
- 在
SpringSecurity
中所有的过滤器形成的调用链就是用的是责任链模式