设计模式之责任链模式(Java实现)

简介: 设计模式之责任链模式(Java实现)

一、认识责任链模式


责任链模式定义:为请求创建了一个接受者对象的链。为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。


该模式又叫职责链模式。

结构:


抽象处理者:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

具体处理者:实现抽象处理者的处理方法,该处理方法中会进行判断能够处理本次请求,如果可以则将请求转给其后继者继续执行处理方法。

结构图如下:



优缺点:


优点:请求的发送者和接受者解耦;可以控制执行顺序;符合开闭原则和单一职责原则。

缺点:对比较长的职责链,请求处理可能会涉及多个处理对象,性能会受到影响;增加了客户端的复杂性,可能会造成循环调用。

应用场景:


Tomcat中的过滤器链使用到了责任链模式,其中ApplicationFilterChain类实现了FilterChain接口,其底层实现使用的是数组,关键方式是doFilter()及internalDoFilter()方法。


二、实现责任链模式


该案例是在学习视频案例之后手敲了一下,视频:2020年最详细的23种Java设计模式完整视频教程全集



demo见xyz.changlu.chain包下代码:



请求对象:Request


//实例对象:通过其中属性来判定其中的执行是否有效
public class Request {
    private boolean requestFrequency;//请求频率
    private boolean loginAuthentication;//登陆认证
    private boolean accessPermission;//访问权限
    public Request(RequestBuilder builder){
        this.requestFrequency = builder.requestFrequency;
        this.loginAuthentication = builder.loginAuthentication;
        this.accessPermission = builder.accessPermission;
    }
    static class RequestBuilder{
        private boolean requestFrequency;//请求频率
        private boolean loginAuthentication;//登陆认证
        private boolean accessPermission;//访问权限
        public RequestBuilder setRequestFrequency(boolean requestFrequency){
            this.requestFrequency = requestFrequency;
            return this;
        }
        public RequestBuilder setLoginAuthentication(boolean loginAuthentication){
            this.loginAuthentication = loginAuthentication;
            return this;
        }
        public RequestBuilder setAccessPermission(boolean accessPermission){
            this.accessPermission = accessPermission;
            return this;
        }
        public Request build(){
            return new Request(this);
        }
    }
    public boolean isRequestFrequency() {
        return requestFrequency;
    }
    public boolean isLoginAuthentication() {
        return loginAuthentication;
    }
    public boolean isAccessPermission() {
        return accessPermission;
    }
}


内部使用到了建造者模式来方便进行赋值操作!

抽象处理者:Handler


//抽象处理者
public abstract class Handler {
    private Handler next;
    public Handler(Handler handler){
        this.next = handler;
    }
    public Handler getNext() {
        return next;
    }
    public void setNext(Handler next) {
        this.next = next;
    }
    abstract boolean process(Request request);
}



包含了具体方法以及抽象方法,该类实际上是使用链表进行连接的,其抽象方法是留给对应的子类来进行实现其中的执行过程。

具体处理者1:RequestFrequencyHandler


//具体处理者1:请求频率处理器
public class RequestFrequencyHandler extends Handler{
    public RequestFrequencyHandler(Handler handler) {
        super(handler);
    }
    @Override
    boolean process(Request request) {
        System.out.println("开始执行请求频率....");
        //1、判断请求频率是否符合规则
        if(request.isRequestFrequency()){
            System.out.println("执行请求频率正常,通过!");
            Handler handler = this.getNext();
            //表示通过
            if (handler != null) {
                //2、执行其下一个处理器(登陆验证)
                if (!handler.process(request)) {
                    return false;
                }
            }
            return true;
        }
        //请求频率过多失败
        System.out.println("请求频率过多失败!");
        return false;
    }
}



具体处理者2:LoginAuthenticationHandler


//登陆认证处理器
public class LoginAuthenticationHandler extends Handler{
    public LoginAuthenticationHandler(Handler handler) {
        super(handler);
    }
    @Override
    boolean process(Request request) {
        System.out.println("开始执行登陆验证....");
        //1、判断登陆验证是否通过
        if(request.isLoginAuthentication()){
            System.out.println("登陆验证通过!");
            Handler handler = this.getNext();
            //判断是否有下个执行器(本案例无)
            if (handler != null) {
                //2、判断是下个执行器是否通过(本案例是不会执行到这里的)
                if (!handler.process(request)) {
                    return false;
                }
            }
            return true;
        }
        //登陆认证失败
        System.out.println("登陆认证失败!");
        return false;
    }
}


与处理者1大致相同,也包含了执行其关联的下一个执行器。

测试程序:测试类Customer


①测试两个false情况


//测试类
public class Customer {
    public static void main(String[] args) {
        //设置request对象的属性
        Request request = new Request.RequestBuilder().setRequestFrequency(false).setLoginAuthentication(false).build();
        //将登陆认证执行放置到请求频率执行器之后
        RequestFrequencyHandler requestFrequencyHandler = new RequestFrequencyHandler(new LoginAuthenticationHandler(null));
        //开始执行
        requestFrequencyHandler.process(request);
    }
}



②测试两个true请求



说明:可以看到按照设置执行器顺序依次执行下去(就像一个链条一样),一旦有个执行方法不通过则会直接结束。



总结


责任链模式通常使用于如处理的是单个请求需要有多个请求处理者来处理不同的事情,将多个处理者链接起来。处理者可通过继承一个抽象类来实现其中的处理方法,并且若是其中情况成立可执行下一个请求处理者,形成一个执行链。

相关文章
|
2月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
2月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
40 4
|
2月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
45 3
|
3月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
59 9
|
2月前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
27 0
|
3月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
57 0
[Java]23种设计模式
|
2月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
2月前
|
设计模式 JavaScript Scala
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
Kotlin教程笔记(55) - 改良设计模式 - 责任链模式
40 0
|
3月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
本教程详细讲解了Kotlin语法,适合需要深入了解Kotlin的开发者。对于希望快速上手Kotlin的读者,推荐查阅“简洁”系列教程。本文通过学生会经费申请的例子,介绍了责任链模式及其在Kotlin中的实现,并使用偏函数进行了改进,使代码更加简洁和灵活。
19 0
|
3月前
|
设计模式 JavaScript Scala
Kotlin - 改良设计模式 - 责任链模式
Kotlin - 改良设计模式 - 责任链模式
42 0