设计模式——责任链模式

news2024/9/24 7:14:35

是什么?

场景案例:假设我们现在在公司里面需要请假,那么如果请假的天数比较少,可以直接找组长请假,但是如果是一个星期这种假的话就还需要去找部门主管,如果是半个月以上的假的话就还需要去找副总经理甚至总经理请假,员工要根据自己请假的天数去找不同的领导进行审批,也就是说员工必须要记住每个领导的姓名以及职责等信息,这就增加了难度;

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

结构

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

具体处理者:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者;

客户类:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程;

实现

抽象处理者

public abstract class AbstractProcessor {
    //抽象处理者
    public static final Integer NUM_THREE=3;
    public static final Integer NUM_SEVEN=7;
    public static final Integer NUM_FIFTEEN=15;
    //设置当前管理员的审批天数范围和下一级领导
    protected Integer start;
    protected Integer end;
    protected AbstractProcessor nextHandler;
    
    public AbstractProcessor(Integer start,Integer end){
        this.start=start;
        this.end=end;
    }
    //当前管理员的具体审批
    protected abstract void leave(LeaveRequest leaveRequest);
    //执行管理员的审批,并且判断是否需要提交给下一级管理员进行审批(递归)
    public void submit(LeaveRequest leaveRequest){
        this.leave(leaveRequest);
        if (leaveRequest.getDays()>=end&&nextHandler!=null){
            nextHandler.submit(leaveRequest);
        }else {
            System.out.println("审批完成,流程结束!");
        }
    }
}

具体处理者

public class GroupLeader extends AbstractProcessor{
//小组组长审批
    public GroupLeader(Integer start, Integer end) {
        super(1, AbstractProcessor.NUM_THREE);
        this.nextHandler=new DepManager(AbstractProcessor.NUM_THREE, AbstractProcessor.NUM_SEVEN);
    }

    @Override
    protected void leave(LeaveRequest leaveRequest) {
        System.out.println("组长审批同意"+leaveRequest.getName()+"因"+leaveRequest.getDesc()+"请假"+leaveRequest.getDays()+"天");

    }
}
public class DepManager extends AbstractProcessor{
    //经理审批
    public DepManager(Integer start, Integer end) {
        super(AbstractProcessor.NUM_THREE, AbstractProcessor.NUM_SEVEN);
        this.nextHandler=new Leader(AbstractProcessor.NUM_SEVEN, AbstractProcessor.NUM_FIFTEEN);
    }


    @Override
    protected void leave(LeaveRequest leaveRequest) {
        System.out.println("经理审批同意"+leaveRequest.getName()+"因"+leaveRequest.getDesc()+"请假"+leaveRequest.getDays()+"天");
    }
}

public class Leader extends AbstractProcessor{
    //经理审批
    public Leader(Integer start, Integer end) {
        super(AbstractProcessor.NUM_SEVEN, AbstractProcessor.NUM_FIFTEEN);
        this.nextHandler=new CEO(AbstractProcessor.NUM_FIFTEEN, 999);
    }

    @Override
    protected void leave(LeaveRequest leaveRequest) {
        System.out.println("经理审批同意"+leaveRequest.getName()+"因"+leaveRequest.getDesc()+"请假"+leaveRequest.getDays()+"天");

    }
}
public class CEO extends AbstractProcessor{
    //老板审批
    public CEO(Integer start, Integer end) {
        super(AbstractProcessor.NUM_FIFTEEN, 999);
        super.nextHandler=null;
    }


    @Override
    protected void leave(LeaveRequest leaveRequest) {
        System.out.println("天数太长不允许请假,滚出去");
    }
}

客户类

public class Leave {
    //封装处理器链,给外部员工请假时调用,这样可以隐藏一些信息,让员工在调用的时候只用关心自己的请假条和调用该方法即可
    public static void doLeave(LeaveRequest leaveRequest){
        GroupLeader group = new GroupLeader(1, AbstractProcessor.NUM_THREE);
        group.submit(leaveRequest);
    }
}

员工使用

public class Staff {
    public static void main(String[] args) {
        LeaveRequest leaveRequest = new LeaveRequest("Strine", 16, "病假");
        Leave.doLeave(leaveRequest);
    }
}

 优缺点

优点

1.降低了对象之间的耦合度;

该模式降低了请求发送者和接受者的耦合度;

2.增强了系统的可扩展性;

可以根据需要增加新的请求处理类,满足开闭原则;

3.增强了给对象指派职责的灵活性;

当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除责任;

4.责任链简化了对象之间的连接;

一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的if或者if...else语句(递归);

5.责任分担;

每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则;

缺点

1.不能保证每个请求一定被处理,由于一个请求没有处理的接受者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理;

2.对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响;

3.职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

win10安装Anaconda巨详细[更新于2023.5.7]

目录 一、Anaconda下载(官网和清华源,更推荐清华源) 1.1、Anaconda官网首页地址 1.2、清华源Anaconda地址 二、Anaconda安装 三、测试Anaconda是否安装配置成功 一、Anaconda下载(官网和清华源,更推荐清华源) 1.1、Anaconda…

烽火HG680-J_Hi3798MV100_内有普通版和高安版-当贝桌面-卡刷强刷固件包

烽火HG680-J_Hi3798MV100_内有普通版和高安版-当贝桌面-卡刷强刷固件包-内有短接图和教程 特点: 1、适用于对应型号的电视盒子刷机; 2、开放原厂固件屏蔽的市场安装和u盘安装apk; 3、修改dns,三网通用; 4、大量精…

树【二叉树】与森林的相互转化与遍历

一、树与森林的相互转换 预备知识:孩子兄弟表示法。 代码编写出来: typedef struct CSNode{int data;struct CSNode *firstchild,*nextS; }CSNode; 解释:该结点的链域分别指向它的第一个孩子和它同级的兄弟。 (一)森…

【场景方案】我所遇到的有关前端文件上传的知识点归纳,欢迎大家来补充

文章目录 前言前后端传输的文件格式主要有哪些base64formData 前端上传方案input标签获取文件HTML5的API 切片上传大文件blob数据转成base64未来不间断补充 前言 本文章总结了本人在网上和实际公司项目中遇到的有关前端文件上传功能的知识点,如有更好的方案或者发现…

【Windows】【Audio】Windows 11 声音配置

目录 一. 问题 二. 步骤 三. 配置 3.1 候选列表 3.2 程序事件 3.2.1 Windows 3.2.2 文件资源管理器 3.2.3 Windows 语音识别 一. 问题 印象中记得 Windows XP 启动和关机,还有平常点击的过程中有声音来着,Windows 11 咋没有? 折腾了折…

智能优化算法:浣熊优化算法-附代码

智能优化算法:浣熊优化算法 文章目录 智能优化算法:浣熊优化算法1.浣熊优化算法1.1 初始化1.2 阶段一:狩猎和攻击(探索阶段) 2.实验结果3.参考文献4. Matlab 摘要:浣熊优化算法(Coati Optimizat…

Mysql的可重复读解决了幻读问题吗

针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据&…

开关电源基础02:基本开关电源拓扑(3)-拓扑分析

说在开头:关于薛定谔的波动方程(1) 当年毛头小子海森堡在哥廷根求学的时候,埃尔文.薛定谔已经是瑞士苏黎世大学的著名教授了。跟其他那些小天才(定位精度:25岁5岁)相比,薛定谔只能用…

使用 Python 查找本月的最后一天

文章目录 使用 Python 中的日历库查找月份的最后一天使用 Python 中的 DateTime 模块查找该月的最后一天从每个月的第一天减去一天以找到该月的最后一天使用存储在数组中的预加载日期使用 for 循环查找该月的最后一天打印日历年所有月份的最后一天以查找该月的最后一天 使用 Ar…

Kafka生产者原理

消息发送流程介绍 Producer创建时,会创建⼀个sender线程并设置为守护线程。⽣产消息时,内部其实是异步的;⽣产的消息先经过拦截器->序列化器->分区器,然后将消息缓存在缓冲区(该缓冲区也是在Producer创建时创建…

关于clash退出后,华硕电脑连不上网了

关于clash退出后,华硕电脑连不上网了 问题记录 问题记录 昨天因为overleaf老断网,然后我就挂了一下clash(第一次用,不怎么懂),后来直接关闭退出了。 今天早上突然浏览器的网页(微软自带、华硕…

挑战14天学完Python----初识Python语法

往期文章 Java继承与组合 你知道为什么会划分数据类型吗?—JAVA数据类型与变量 10 > 20 && 10 / 0 0等于串联小灯泡?—JAVA运算符 你真的知道怎样用java敲出Hello World吗?—初识JAVA 目录 往期文章前言1.温度转换实例2. 程序格式框架2.1 高…

ATT汇编快速学习

说明 文档来源 https://flint.cs.yale.edu/cs421/papers/x86-asm/asm.html 使用AT&T语法; 原文档是intel语法翻译过来的; 内容 基于32位, x86的硬件环境; 指令仅仅介绍常用, 即还有很大一部分的指令并没有支持; 编译器(汇编器) GAS(GNU assembler: 即gnu组织提供; 使…

《斯坦福数据挖掘教程·第三版》读书笔记(英文版)Chapter 5 Link Analysis

来源:《斯坦福数据挖掘教程第三版》对应的公开英文书和PPT Chapter 5 Link Analysis Terms: words or other strings of characters other than white space. An inverted index is a data structure that makes it easy, given a term, to find (pointers to) a…

【数码】收音机,德生PL380使用教程与注意事项

文章目录 1、主界面功能介绍(注意闹钟和自动关机)2、电池和电池模式的匹配3、收音机天线与信号,耳机与噪音F、参考资料 1、主界面功能介绍(注意闹钟和自动关机) 红色的按钮:power 按一下开机,按…

DJYOS开源往事一:djyos爱好者大南山相聚写实

前言:DJYOS开源社区成立于2009年,后因为专注技术方向和垂直产业化等原因,2015年后关闭开源社区。斗转星移,DJYOS开源社区虽然关闭,但是DJYOS开源和精神依然在,转眼DJYOS发布十四年了。记录一下DJYOS开源往事…

Qt Plugin插件开发

一、Qt 插件机制 .1 Qt 插件简介 插件是一种遵循一定规范的应用程序接口编写出来的程序,定位于开发实现应用软件平台不具备的功能的程序。插件与宿主程序之间通过接口联系,就像硬件插卡一样,可以被随时删除,插入和修改&#xff…

2.2.4 Linux安装模式下,磁盘分区的选择(重要)

目录树结构 (directory tree) 整个Linux系统最重要的地方就是在于目录树架构。 所谓的目录树架构(directory tree)就是以根目录为主,然后向下呈现分支状的目录结构的一种文件架构。 所以,整个目录树架构最重…

Midjourney-Discord入门+高手指引手册

上一篇我们说了如何注册和订阅,今天我们来讲一讲相关的细节,首先我们来一个概览图,先有个大致的印象。 概览图 生成的四张图片,类似于Demo,从左至右,从上至下,1,2,3,4放大按钮U1,U2…