【设计模式专题】责任链模式实战讲解

简介: 【设计模式专题】责任链模式实战讲解

正文


一 什么是责任链模式


责任链模式是一种让校验逻辑与业务解耦的一种设计模式,让每个节点都有自己的处理器,处理器去处理具体逻辑,并且每个节点都有对下一个节点的引用,类似于没有prev的单向链表,当前节点指向下一个节点。


当调用方法时,沿着预定的链路依次对每个节点进行处理,直到某个节点被终止或整条链路处理完成。


让调用方法者不用在意方法内的校验逻辑,只需要关注业务逻辑,让业务结构更加清晰。


二 什么时候使用责任链模式


比如一次请求,A条件不满足时立马return,B条件不满足时return,C条件不满足时return等等,所有的校验完成后开始进行业务逻辑。

第一 此时如果又发起了一个其他的请求那么又需要copy一份相同校验代码,完全没有进行复用。


第二 没有和业务解耦,代码中有60%都是校验代码,40%业务代码,头重脚轻。


如果我调用一个方法我肯定是不关心他校验的代码,我只关心它的业务代码,所以调用方法时需要观察大量无用代码,那么此时我们就可以使用责任链模式了。


三 实战


import lombok.Data;
/**
 * @Author liuy
 * @Description 用户信息
 * @Date 2022/7/29 17:47
 * @Version 1.0
 */
@Data
public class User {
 private String userName;
 private String password;
 private Integer age;
}
import lombok.Data;
/**
 * 责任链处理器抽象类
 * @param <T>
 */
@Data
public abstract class Handler<T> {
    protected Handler next;
    //寻找下一个校验节点
    private void next(Handler next) {
        this.next = next;
    }
    public abstract void doHandler(User m);
    public static class Builder<T> {
        private Handler<T> head;
        private Handler<T> tail;
        public Builder<T> addHandler(Handler handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }
            this.tail.next(handler);
            this.tail = handler;
            return this;
        }
        public Handler<T> build() {
            return this.head;
        }
    }
}
import com.ruoyi.common.utils.StringUtils;
/**
 * 登录校验处理器
 */
public class LoginHandler extends Handler {
    @Override
    public void doHandler(User member) {
        if (StringUtils.isEmpty(member.getUserName()) ||
                StringUtils.isEmpty(member.getPassword())) {
            System.out.println("请填写用户名或密码");
            return;
        }
        if (null != next) {
            next.doHandler(member);
        }
    }
}
/**
 * 年龄校验处理器
 */
public class AgeHandler extends Handler {
    public AgeHandler() {
    }
    //建造者模式 再建造一些责任链中某个单位的子链路
    public AgeHandler(Handler.Builder builder) {
        builder.addHandler(new AgeMinHandler())
               .addHandler(new AgeMaxHandler());
    }
    @Override
    public void doHandler(User member) {
        if (member.getAge() == null || member.getAge() == 0) {
            System.out.println("请填写年龄");
            return;
        }
        if (null != next) {
            next.doHandler(member);
        }
    }
    public static class AgeMinHandler extends Handler {
        @Override
        public void doHandler(User member) {
            if (member.getAge() < 22 ) {
                System.out.println("还没毕业 不要");
                return;
            }
            if (null != next) {
                next.doHandler(member);
            }
        }
    }
    public static class AgeMaxHandler extends Handler {
        @Override
        public void doHandler(User member) {
            if (member.getAge() > 35) {
                System.out.println("年龄太大 不要");
                return;
            }
            if (null != next) {
                next.doHandler(member);
            }
        }
    }
}

测试

/**
 * @Author liuy
 * @Description 测试类
 * @Date 2022/8/3 16:03
 * @Version 1.0
 */
public class HandlerTest {
    public static void main(String[] args) {
        User member = new User();
        member.setUserName("admin");
        member.setPassword("123");
        member.setAge(36);
        Handler.Builder builder = new Handler.Builder();
        //添加链路节点
        builder.addHandler(new AgeHandler(builder))
        .addHandler(new LoginHandler());
        builder.build().doHandler(member);
    }
}

结果

11233.png

我们预设了责任链:LoginHandler——>AgeHandler,那么一个请求就会验证这个责任链一步步往后传递,要么被某个节点return终止,要么直至最后处理完成。


四、使用案例


JDK中的Filter,它是一个接口,类似我们的抽象Handler,它的子类实现其中的doFilter方法;


五、模式总结


5.1 优点


将请求和处理进行解耦;请求处理者只关注自己感兴趣的请求进行处理,对于不感兴趣的交给下一个节点处理;

具备链式传递处理能力,请求发送者不需要知道全局链路,符合迪米特法则(最少只是原则);

链路结构灵活,可以通过改变链路结构动态地增减责任,符合开闭原则;


5.2 缺点


责任链太长或者某个处理节点处理时间过长,会影响整体的性能;

如果处理节点存在循环引用,会造成死循环;


相关文章
|
5月前
|
设计模式 前端开发 JavaScript
【JavaScript 技术专栏】JavaScript 设计模式与实战应用
【4月更文挑战第30天】本文探讨JavaScript设计模式在提升开发效率和代码质量中的关键作用。涵盖单例、工厂、观察者、装饰器和策略模式,并通过实例阐述其在全局状态管理、复杂对象创建、实时数据更新、功能扩展和算法切换的应用。理解并运用这些模式能帮助开发者应对复杂项目,提升前端开发能力。
59 0
|
5月前
|
设计模式 Java
【设计模式系列笔记】责任链模式
责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到有一个处理者能够处理它。每个处理者都有一个对下一个处理者的引用。责任链模式常用于处理请求的场景,例如在一个请求需要经过多个步骤或者多个对象来处理的情况下。
61 0
|
5月前
|
设计模式 存储 uml
C++ 设计模式实战:外观模式和访问者模式的结合使用,派生类访问基类的私有子系统
C++ 设计模式实战:外观模式和访问者模式的结合使用,派生类访问基类的私有子系统
60 1
|
5月前
|
设计模式 Java
【设计模式】责任链模式
【设计模式】责任链模式
|
9天前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)
|
28天前
|
设计模式 C# 开发者
C#设计模式入门实战教程
C#设计模式入门实战教程
|
2月前
|
前端开发 开发者 开发框架
JSF与Bootstrap,打造梦幻响应式网页!让你的应用跨设备,让用户爱不释手!
【8月更文挑战第31天】在现代Web应用开发中,响应式设计至关重要,以确保不同设备上的良好用户体验。本文探讨了JSF(JavaServer Faces)与Bootstrap框架的结合使用,展示了如何构建响应式网页。JSF是一个基于Java的Web应用框架,提供丰富的UI组件和表单处理功能;而Bootstrap则是一个基于HTML、CSS和JavaScript的前端框架,专注于实现响应式设计。通过结合两者的优势,开发者能够更便捷地创建自适应布局,提升Web应用体验。然而,这种组合也有其局限性,如JSF组件库较小和较高的学习成本等,因此在选择开发框架时需综合考虑具体需求和应用场景。
33 0
|
2月前
|
设计模式 前端开发 开发者
Angular携手Material Design:探索设计模式下的UI组件开发之道——从按钮到对话框的全面实战演示
【8月更文挑战第31天】在现代Web应用开发中,Angular框架结合Material Design设计原则与组件库,显著提升了用户界面的质量与开发效率。本文通过具体代码示例,详细介绍如何在Angular项目中引入并使用Material Design的UI组件,包括按钮、表单和对话框等,帮助开发者快速构建美观且功能强大的应用。通过这种方式,不仅能提高开发效率,还能确保界面设计的一致性和高质量,为用户提供卓越的体验。
22 0
|
2月前
|
设计模式 存储 Java
掌握Java设计模式的23种武器(全):深入解析与实战示例
掌握Java设计模式的23种武器(全):深入解析与实战示例
|
4月前
|
设计模式 Java 中间件
深入探索Java设计模式:责任链模式解析与实践
深入探索Java设计模式:责任链模式解析与实践
48 0