Java实现责任链模式

news/2024/5/19 14:50:40 标签: java, 责任链模式, 开发语言

责任链模式是一种设计模式,用于处理请求的解耦。在责任链模式中,多个对象都有机会处理请求,从而避免了请求发送者和接收者之间的直接依赖关系。每个处理者都可以决定是否处理请求以及将请求传递给下一个处理者。

简介

责任链模式由一条链组成,每个处理者都有一个对下一个处理者的引用。当请求进入链中时,从链的开头开始依次询问每个处理者是否能够处理该请求。如果某个处理者能够处理请求,则处理请求并结束链,否则将请求传递给下一个处理者。这样,请求会在链上依次传递,直到有一个处理者能够处理请求或者到达链的末尾。

使用场景

责任链模式因为可以灵活地配置处理者的顺序和数量,而不需要修改客户端代码。所以责任链模式在项目实战中用处广泛。

  • JDK中的异常处理机制就使用了责任链模式。当某个方法抛出异常时,首先会在方法内部寻找try-catch块来捕获异常,如果没有找到,就会将异常向上一层抛出,直至找到合适的catch块处理。
  • Spring框架中的拦截器链机制也使用了责任链模式。拦截器链是通过将各个拦截器按照一定的顺序连接起来形成一个链条,在请求处理过程中按顺序调用每个拦截器的相应方法来完成一系列操作。

责任链模式还可以用于处理日志记录、用户权限验证等场景。

开发实例

现在我简单用Java代码实现责任链模式,帮助大家快速入门理解

定义责任链抽象类

首先需要定义责任链抽象类,其作用是定义一个抽象的责任链,将处理请求的对象串联起来,并且定义了处理请求的方法。

@Data
public abstract class AbstractHandler<T> {
    protected String name;

    protected AbstractHandler<T>  nextHandler;

    public AbstractHandler(String name){
        this.name = name;
    }

    public boolean hasNextHandler(){
        return nextHandler != null;
    }

    /**
     * 业务处理方法
     * @param t 传入参数
     * @return
     */
    public abstract T process(T t);
}

具体业务处理类

业务处理类1

/**
 * 将传入的数字加2
 */
public class AddTwoHandler extends AbstractHandler<Integer>{

    public AddTwoHandler(String name) {
        super(name);
    }

    @Override
    public Integer process(Integer t) {
        t = t + 2;
        if(hasNextHandler()) {
            return nextHandler.process(t);
        }
        return t;
    }
}

业务处理类2

/**
 * 将传入的数字乘3
 */
public class MultiThreeHandler extends AbstractHandler<Integer>{
    public MultiThreeHandler(String name) {
        super(name);
    }

    @Override
    public Integer process(Integer t) {
        t = t * 3;
        if(hasNextHandler()) {
            return nextHandler.process(t);
        }
        return t;
    }
}

业务处理类3

/**
 *  将传入的数字减1
 */
public class DecreaseOneHandler extends AbstractHandler<Integer>{
    public DecreaseOneHandler(String name) {
        super(name);
    }

    @Override
    public Integer process(Integer t) {
        t = t - 1;
        if(hasNextHandler()) {
            return nextHandler.process(t);
        }
        return t;
    }
}

代码测试

public class ChainTest {
    public static void main(String[] args) {
        AddTwoHandler two = new AddTwoHandler("加2");
        DecreaseOneHandler one = new DecreaseOneHandler("减1");
        MultiThreeHandler three = new MultiThreeHandler("乘3");

        two.nextHandler = one;
        one.nextHandler = three;

        Integer result = two.process(5);
        System.out.println(result);
    }
}

实现业务处理是,开始值是5,开始执行“加2”操作 ,之后执行“减1”操作,在之后执行“乘3”操作,最后输出结果18。

在不改变代码的情况下,如果修改链式的处理顺序,那结果也就完全不一样了,这就带来很多可扩展性,我们可以很灵活地改变处理者的顺序和添加新的处理者。


http://www.niftyadmin.cn/n/5310057.html

相关文章

【csharp】依赖注入

依赖注入 依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是一种软件设计模式&#xff0c;旨在降低组件之间的耦合度。在依赖注入中&#xff0c;一个类的依赖关系不是在类内部创建&#xff0c;而是通过外部传递进来。这通常通过构造函数、方法参数或属性…

SpringBoot 中实现订单30分钟自动取消的策略

简介 在电商和其他涉及到在线支付的应用中&#xff0c;通常需要实现一个功能&#xff1a;如果用户在生成订单后的一定时间内未完成支付&#xff0c;系统将自动取消该订单。 本文将详细介绍基于Spring Boot框架实现订单30分钟内未支付自动取消的几种方案&#xff0c;并提供实例…

Linux系统常用的安全优化

环境&#xff1a;CentOS7.9 1、禁用SELinux SELinux是美国国家安全局对于强制访问控制的实现 1)永久禁用SELinux vim /etc/selinux/config SELINUXdisabled #必须重启系统才能生效2&#xff09;临时禁用SELInux getenforce #查看SELInux当前状态 setenforce 0 #数字…

WiFi7: 使用Multi-Link Element告知ML信息之概述

原文:在Beacon 或Probe Response帧中包含Basic Multi-Link element由35.3.4(AP MLD的发现)描述。在认证, FT Action, (重)关联请求,(重)关联响应帧包含此element的规则在35.3.5(ML (重)建立)描述。Basic Multi-Link element中是否有Link Info域,有的话,Link Info域是携…

杨中科.NET Core 教程 第一部分-2- .NET Core的重要问题

.NETCore 和 .NETFramework区别 尽管绝大部分用法都没变&#xff0c;但是.NET Core不是 .NET Framework的升级版&#xff0c;无法直接升级 用Mono&#xff0c;.NET Framework程序可以直接运行在Linux下。有了Mono&#xff0c;为啥微软还搞.NET Core? .NET Framework缺点&am…

【软件测试】学习笔记-如何做好单元测试

什么是单元测试&#xff1f; 在正式开始今天的话题之前&#xff0c;我先给你分享一个工厂生产电视机的例子。 工厂首先会将各种电子元器件按照图纸组装在一起构成各个功能电路板&#xff0c;比如供电板、音视频解码板、射频接收板等&#xff0c;然后再将这些电路板组装起来构…

Unity中Shader面片一直面向摄像机

文章目录 前言一、实现思路1、 我们要实现模型面片一直跟着摄像机旋转&#xff0c;那么就需要用到旋转矩阵2、确定 原坐标系 和 目标坐标系3、确定旋转后坐标系基向量 二、确定旋转后 坐标系基向量 在 原坐标系 下的值1、Z轴基向量2、假设Y轴基向量 和 世界空间下 的Y轴方向一致…

报错curl: (6) Could not resolve host: raw.githubusercontent...的解决办法

我起初想要在macOS系统安装pip包&#xff0c;首先在终端安装homebrew&#xff0c;敲了命令&#xff1a;/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent...)" 之后触发的报错&#xff0c;报错内容&#xff1a;curl: (6) Could not resolve host: raw.…