Java设计模式:责任链模式

❤ 作者主页:欢迎来到我的技术博客😎
❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~*
🍊 如果文章对您有帮助,记得关注点赞收藏评论⭐️⭐️⭐️
📣 您的支持将是我创作的动力,让我们一起加油进步吧!!!🎉🎉

文章目录

  • 一、责任链模式的定义
  • 二、责任链模式的结构
  • 三、责任链模式的实现
  • 四、责任链模式的优缺点
  • 五、责任链模式的使用场景

一、责任链模式的定义

责任链模式(Chain of Responsibility)又名 职责链模式,是一种行为设计模式,它允许你构建一个由多个对象组成的链,每个对象都有机会处理请求,或者将请求传递给链中的下一个对象。这种模式常用于处理请求的对象之间存在 层次关系 的情况。责任链模式的主要目的是解耦发送者和接收者,使多个对象都有机会处理请求,而不是将请求发送者与接收者硬编码在一起。

在责任链模式中,每个处理者都包含一个对下一个处理者的引用,形成一个链条。当请求进入链条时,从链条的头部开始逐个处理,直到找到能够处理该请求的对象为止。如果没有找到合适的处理者,请求可以被忽略或者采取默认的处理方式。


二、责任链模式的结构

责任链模式包含以下的重要角色:

  • 抽象处理者(Handler): 定义一个处理请求的接口,包含抽象处理方法并维护一个对下一个处理者的引用;
  • 具体处理者(Concrete Handler): 实现处理请求的接口,判断能否处理本次请求,如果能够处理则处理,否则将请求传递给下一个处理者。
  • 客户端类(Client): 创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

三、责任链模式的实现

需求案例:在公司的采购审批流程中,一般根据采购金额的不同需要由不同角色的领导来进行审核。例如,采购部的员工发出采购申请的请求(包含采购金额),一开始是组长接受请求并处理:

  • 如果采购金额小于2000的话,则组长可以直接同意批准采购;
  • 如果采购金额介于2000到5000之间的话,则组长同意批准采购之后还需要将采购申请提交到给经理,由经理审核是否同意批准采购;
  • 如果采购金额大于5000,则不仅需要组长和经理审核同意,还需要由经理将采购申请提交到总经理,由总经理再次审核是否同意批准采购。

类似于上述的业务场景使用责任链模式就可以很好地解决问题。

具体的流程如下:
在这里插入图片描述
 
使用责任链模式实现上述案例,类图如下:

在这里插入图片描述
 
具体的类设计如下:

抽象处理者类:

public abstract class HandleRequest {

    //声明上级领导
    public HandleRequest nextHandle;

    //设置上级领导对象
    public void  setHandleRequest(HandleRequest nextHandle) {
        this.nextHandle = nextHandle;
    }

    //提交采购请求
    public abstract void handleLeaveRequest(LeaveRequest leaveRequest);
}

组长类(具体的处理者):

public class GroupLeader extends HandleRequest{
    
    @Override
    public void handleLeaveRequest(LeaveRequest leaveRequest) {
        if (leaveRequest.getAmount() < 2000) {
            System.out.println("采购流程审核结果:组长同意批准采购");
            System.out.println("采购流程审核结束");
        } else if (nextHandle != null) {
            System.out.println("审核第一步:组长同意批准采购, 等待上级领导审核中...");
            nextHandle.handleLeaveRequest(leaveRequest);
        }
    }
    
}

经理类(具体的处理者):

public class Manage extends HandleRequest{

    @Override
    public void handleLeaveRequest(LeaveRequest leaveRequest) {
        if (leaveRequest.getAmount() >= 2000 && leaveRequest.getAmount() <= 5000) {
            System.out.println("采购流程审核结果:经理同意批准采购");
            System.out.println("采购流程审核结束");
        } else if (nextHandle != null) {
            System.out.println("审核第二步:经理同意批准采购, 等待上级领导审核中...");
            nextHandle.handleLeaveRequest(leaveRequest);
        }
    }
 
}

总经理类(具体的处理者):

public class GeneralManager extends HandleRequest{
    
    @Override
    public void handleLeaveRequest(LeaveRequest leaveRequest) {
        if (leaveRequest.getAmount() > 5000) {
            System.out.println("采购流程审核结果:总经理同意批准采购");
            System.out.println("采购流程审核结束");
        } else {
            System.out.println("不同意该采购申请");
        }
    }
    
}

采购请求类:

public class LeaveRequest {

    private double amount;

    public LeaveRequest(double amount) {
        this.amount = amount;
    }

    public double getAmount() {
        return amount;
    }

}

客户端类:

public class Client {

    public static void main(String[] args) {

        //创建责任链
        GroupLeader groupLeader = new GroupLeader();
        Manage manage = new Manage();
        GeneralManager generalManager = new GeneralManager();

        //设置责任链关系
        groupLeader.setHandleRequest(manage);
        manage.setHandleRequest(generalManager);

        //发起采购请求
        LeaveRequest request1 = new LeaveRequest(1600);
        LeaveRequest request2 = new LeaveRequest(3800);
        LeaveRequest request3 = new LeaveRequest(6200);

        //处理采购请求
        System.out.println("------采购金额为1600的审核流程情况------");
        groupLeader.handleLeaveRequest(request1);
        System.out.println("------采购金额为3800的审核流程情况------");
        groupLeader.handleLeaveRequest(request2);
        System.out.println("------采购金额为6200的审核流程情况------");
        groupLeader.handleLeaveRequest(request3);

    }
}

测试结果如下:
在这里插入图片描述


四、责任链模式的优缺点

优点:

  1. 松散耦合: 责任链模式使得请求发送者和接收者解耦,每个处理者仅需关心自己能否处理请求,而不需要知道整个处理流程的细节。
  2. 灵活性: 可以动态地改变处理者之间的关系和顺序,新增或删除处理者,以适应不同的需求和场景。
  3. 可扩展性: 容易添加新的处理者,无需修改现有的代码,符合开闭原则。
  4. 单一职责原则: 每个具体处理者只负责处理特定类型的请求,符合单一职责原则,使得代码更清晰和可维护。

缺点:

  1. 性能问题: 在责任链比较长的情况下,请求可能需要遍历整个链条才能找到合适的处理者,可能影响性能。
  2. 可能导致请求无法处理: 如果责任链没有被正确配置,或者某个请求没有得到处理,可能导致请求无法被处理。
  3. 不容易观察运行时的特征: 由于责任链的处理者是动态组合的,难以在运行时直观地观察到整个处理流程。
  4. 可能引入安全问题: 如果责任链的配置不当,某个处理者可能被滥用,导致安全问题。

五、责任链模式的使用场景

  1. 审批流程: 当一个请求需要经过多个处理者进行审批时,可以使用责任链模式。每个处理者负责不同级别的审批,直到找到合适的处理者为止。
  2. 日志记录: 在日志系统中,可以使用责任链模式处理不同级别的日志信息。每个处理者对应一个日志级别,形成责任链,便于灵活控制日志的输出。
  3. 事件处理: 当系统中存在多个对象负责处理不同类型的事件时,可以使用责任链模式。每个处理者处理特定类型的事件,形成事件处理链。
  4. 过滤器链: 在需要按顺序执行多个过滤操作的场景中,可以使用责任链模式。每个过滤器负责一个过滤操作,形成过滤器链。
  5. 异常处理: 在异常处理中,可以使用责任链模式处理不同类型的异常。每个处理者负责处理特定类型的异常,形成异常处理链。
  6. 请求转发: 在 Web 开发中,可以使用责任链模式实现请求的转发。每个处理者负责处理特定类型的请求,如果无法处理,则将请求转发给下一个处理者。
  7. 工作流程引擎: 责任链模式可以用于实现工作流程引擎,其中每个节点负责执行一部分工作,流程按照责任链顺序逐步执行。

 
非常感谢您阅读到这里,如果这篇文章对您有帮助,希望能留下您的点赞👍 关注💖 分享👥 留言💬thanks!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/310493.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java基于SSM的旅游论坛设计与实现论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

Python的安装与卸载【Windows系统】

在 Windows 上安装与卸载 Python Python的安装 下载Python 安装Python 下载完后打开安装包 注意最底下的"Add Python 3.8 to Path"&#xff08;将Python加入环境变量&#xff09;一定要勾选&#xff01;&#xff01;&#xff01;这样就可以免去之后环境配置的烦恼…

掌握视频节奏,玩转剪辑艺术!,轻松调整视频播放速度与秒数的技巧大揭秘

你是否经常觉得视频播放得太快或太慢&#xff0c;无法满足你的观看需求&#xff1f;或者想要控制视频的长度&#xff0c;却不知道该如何下手&#xff1f;今天&#xff0c;我们将为你揭秘几种简单又实用的方法&#xff0c;让你轻松调整视频的播放速度和秒数&#xff01; 首先&a…

Linux -- firewalld的富语言规则

1. Firewalld支持两种类型的NAT&#xff1a;IP地址伪装和端口转发。 &#xff08;1&#xff09;IP地址伪装 地址伪装&#xff08;masquerade)&#xff1a;通过地址伪装&#xff0c;NAT 设备将经过设备的包转发到指定接收方&#xff0c;同时将通过的数据包的源地址更改为其自己的…

【tensorflowflutterweb】机器学习模型怎样用到前端上(未写完)

书接上回 在上一章 我们谈了怎么根据项目需求构建一个简单的机器学习模型。 ​​​​​​ ​​​​​​【tensorflow&flutter】自己写个机器学习模型用在项目上&#xff1f;-CSDN博客文章浏览阅读852次&#xff0c;点赞22次&#xff0c;收藏15次。【tensorflow&flutter…

k8s的存储卷之静态

存储卷----数据卷 容器内的目录和宿主机的目录进行挂载 容器在系统上的生命周期是短暂的&#xff0c;delete&#xff0c;k8s用控制创建的pod&#xff0c;delete相当于重启&#xff0c;容器的状态也会回复到初始状态 一旦回到初始状态&#xff0c;所有的后天编辑的文件都会消…

C++力扣题目110--平衡二叉树

给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;t…

大数据系列之:腾讯云服务器性能和价格比较

大数据系列之&#xff1a;腾讯云服务器性能和价格比较 一、磁盘性能和价格比较二、高性能云硬盘三、ssd云硬盘四、极速型ssd云硬盘五、增强型ssd云硬盘六、查看腾讯云服务器价格 一、磁盘性能和价格比较 磁盘名称高性能ssd云硬盘极速型ssd云硬盘增强型ssd云硬盘规格500g 5800 …

UM2003A 一款200 ~ 960MHz ASK/OOK +18dBm 发射功率的单发射芯片

UM2003A 是一款工作于 200 ~ 960MHz 频段的单片集成、高性能、可独立运行的 OOK 发射器。内部集成的 OTP 方便用户对各种射频参数以及特色功能进行编程。该芯片以其高集成度和低功耗的设计&#xff0c;特别适用于低成本&#xff0c;低功耗&#xff0c;电池驱动的无线发射应用。…

Unity URP下阴影锯齿

1.概述 在Unity开发的URP项目中出现阴影有明显锯齿。如下图所示&#xff1a; 并且在主光源的Shadow Type已经是Soft Shadows模式了。 2.URP Asset 阴影出现锯齿说明阴影质量不高&#xff0c;所以要先找到URP Asset文件进行阴影质量参数的设置。 1.打开PlayerSetting找到Graph…

切分大文件sql为小份

数据库太大了&#xff0c;整个备份导入出问题或者慢&#xff0c;需要将整个库按照表分割&#xff08;一个表一个sql文件&#xff09; 环境 win10 工具&#xff1a;python3.7pycharm 要分割的文件大小&#xff1a;6G&#xff0c;sql文件import redbname with open(best**.sql,…

C++标准学习--多线程

在以往多线程的实现的时候&#xff0c;都是自己去亲自创建线程&#xff0c;采用特殊flag 及锁控制线程的运转状态。这无可厚非&#xff0c;但又似乎有重复造轮子的嫌疑。最近发现了一个线程池的轮子&#xff0c;很不错&#xff0c;ZZ一下。 C多线程线程池&#xff08;全详解&a…

理解Herbrand Equivalence

笔者最近在看GVN的一系列论文&#xff0c;总会看到一个概念叫Herbran Equivalence&#xff0c;依靠这种定义&#xff0c;能够判断一个GVN算法是否是complete的&#xff0c;也即检测一个算法是否是precise的&#xff0c;只有找到所有Herbrand Equivalence关系的算法才能称得上是…

Python基础知识:整理9 文件的相关操作

1 文件的打开 # open() 函数打开文件 # open(name, mode, encoding) """name: 文件名&#xff08;可以包含文件所在的具体路径&#xff09;mode: 文件打开模式encoding: 可选参数&#xff0c;表示读取文件的编码格式 """ 2 文件的读取 文…

18-链表-移除链表元素

这是链表的第18题&#xff0c;力扣链接。 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,…

杨中科 .NET项目结构及程序发布

一样的csproj,不一样的接口 1.文件包含于排除&#xff1a; 2. *.config 文件包含于排除 新建 .netcore 与 .netframework 项目 打开framework 项目文件位置 打开 frameworkConsoleApp1.csproj文件 查看 .netcore的CoreconsoleApp2.csproj文件 该文件十分简洁 改变版本…

springCould中的Bus-从小白开始【11】

目录 &#x1f9c2;1.Bus是什么❤️❤️❤️ &#x1f32d;2.什么是总线❤️❤️❤️ &#x1f953;3.rabbitmq❤️❤️❤️ &#x1f95e;4.新建模块3366❤️❤️❤️ &#x1f373;5.设计思想 ❤️❤️❤️ &#x1f37f;6.添加消息总线的支持❤️❤️❤️ &#x1f9…

java将word转换成pdf,并去除水印

注意我这里只是将word字节替换成pdf字节&#xff0c;如果是文件根据自己实际情况来做 1、所需jar包 <dependency><groupId>com.aspose</groupId><artifactId>aspose-words</artifactId><version>15.8.0</version></dependency&g…

模拟超市商品结算系统

要求:全程一个角色(管理员即用户) (1)需要管理员注册与登录 (2)管理员登录之后&#xff0c;可以进行上架新的商品(商品名称和单价) (3)管理员登录之后&#xff0c;也可以下架商品 (4)在节假日有优惠活动,可以对其中的一些商品修改相应的单价(价格提高和价格降低都可以) (5)用户…

JavaScript中alter、confrim、prompt的区别及使用

文章目录 一、alter1.什么是alert&#xff1f;2.alter的使用 二、confrim1.什么是confrim&#xff1f;2.confrim的使用 三、prompt1.什么是prompt&#xff1f;2.prompt的使用 四、总结alter、confrim、prompt的区别 一、alter 1.什么是alert&#xff1f; 在JavaScript中&…