【设计模式】责任链模式


一、责任链模式

一句话总结:比如一个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
  • 说明:其实类图也很简单,两个 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 中所有的过滤器形成的调用链就是用的是责任链模式
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发飙的蜗牛咻咻咻~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值