java设计模式中责任链模式是什么/怎么用责任链模式避免if-else语句

news2024/11/16 20:44:08

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用!

6.5 责任链模式

6.5.1 定义

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

6.5.2 结构

  • 抽象处理者角色(Handler):定义处理接口,包括抽象处理方法和后继连接
  • 具体处理者角色(Concrete Handler):实现抽象处理者方法,判断能否处理本次请求,若可以处理则处理请求,否则将请求转给后继者
  • 客户类角色:创建处理链,并向链头具体处理者对象提交请求,不关心处理细节和请求传递过程

6.5.3 案例(请假)

  • 请假条类
public class LeaveRequest {  
    //姓名  
    private String name;  
//    请假天数  
    private int num;  
//    请假内容  
    private String content;  
    public LeaveRequest(String name, int num, String content) {  
        this.name = name;  
        this.num = num;  
        this.content = content;  
    }  
    public String getName() {  
        return name;  
    }  
    public int getNum() {  
        return num;  
    }  
    public String getContent() {  
        return content;  
    }  
}
  • 抽象处理类
public abstract class Handler {  
    protected final static int NUM_ONE = 1;  
    protected final static int NUM_THREE = 3;  
    protected final static int NUM_SEVEN = 7;  
//  该领导处理的请求天数区间  
    private int numStart;  
    private int numEnd;  
//    声明后续者(上级领导)  
    private Handler nextHandler;  
    public Handler(int numStart, int numEnd) {  
        this.numStart = numStart;  
        this.numEnd = numEnd;  
    }  
    public Handler(int numStart) {  
        this.numStart = numStart;  
    }  
//    设置上级领导对象  
    public void setNextHandler(Handler nextHandler) {  
        this.nextHandler = nextHandler;  
    }  
//    各级领导处理请假条的方法  
    protected abstract void handlerLeave(LeaveRequest leaveRequest);  
//    提交请求  
    public final void submit(LeaveRequest leaveRequest)  
    {  
//        该领导进行审批  
        this.handlerLeave(leaveRequest);  
        if(this.nextHandler != null && leaveRequest.getNum() > this.numEnd)  
//            提交上级领导审批  
            this.nextHandler.submit(leaveRequest);  
        else System.out.println("流程结束!");  
    }  
}
  • 组长类
public class GroupLeader extends Handler{  
    public GroupLeader(){  
        super(0,Handler.NUM_ONE);  
    }  
    protected void handlerLeave(LeaveRequest leaveRequest){  
        System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天," + leaveRequest.getContent() + "。");  
        System.out.println("组长同意审批:同意!");  
    }  
}
  • 部门经理类
public class ManagerLeader extends Handler{  
    public ManagerLeader(){  
        super(Handler.NUM_ONE,Handler.NUM_THREE);  
    }  
    protected void handlerLeave(LeaveRequest leaveRequest){  
        System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天," + leaveRequest.getContent() + "。");  
        System.out.println("部门经理同意审批:同意!");  
    }  
}
  • 总经理类
public class GeneralManagerLeader extends Handler{  
    public GeneralManagerLeader(){  
        super(Handler.NUM_THREE,Handler.NUM_SEVEN);  
    }  
    protected void handlerLeave(LeaveRequest leaveRequest){  
        System.out.println(leaveRequest.getName() + "请假" + leaveRequest.getNum() + "天," + leaveRequest.getContent() + "。");  
        System.out.println("总经理同意审批:同意!");  
    }  
}
  • 测试
    public static void main(String[] args) {  
//        创建请假条对象  
        LeaveRequest leaveRequest = new LeaveRequest("小明",3,"感冒");  
//        创建领导对象  
        GroupLeader groupLeader = new GroupLeader();  
        ManagerLeader managerLeader = new ManagerLeader();  
        GeneralManagerLeader generalManagerLeader = new GeneralManagerLeader();  
//        设置处理者链  
        groupLeader.setNextHandler(managerLeader);  
        managerLeader.setNextHandler(generalManagerLeader);  
//        提交请假申请  
        groupLeader.submit(leaveRequest);  
    }
  • 结果
    ![[Pasted image 20230109230116.png]]
  • 类图![[Pasted image 20230109230242.png]]

6.5.4 优缺点

6.5.4.1 优点

  • 降低了对象间耦合度,也降低了请求发送者和接收者的耦合度
  • 增强了系统的可拓展性,可根据需要增加新的请求处理类,满足开闭原则
  • 增强了给对象指派责任的灵活性,当工作流程发生变化,可以动态地改变链内成员或修改它们的次序,也可动态地修改新增或删除责任
  • 责任链简化了对象间的连接,一个对象只需保持一个指向其后继者的引用,不需保持其它所有处理者的引用,这避免使用了较多的if-else语句判断
  • 责任分担,每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围,复合类的单一职责原则

6.5.4.2 缺点

  • 不能保证每个请求一定做处理,由于一个请求没明确的接收者,所以不能保证一定被处理,该请求可能一直传到链的末端都得不到处理
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能可能受到一定影响
  • 职责链建立的合理性要依靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用

6.5.5源码解析

FilterChain是职责链(过滤器)模式的典型应用,以下是Filter的模拟实现分析:

  • 模拟web请求Request以及web响应Response
  public interface Request {  
}
public interface Response {  
}
  • 模拟Web过滤器Filter
public interface Filter {  
    public void doFilter(Request request, Response response,FilterChain filterChain);  
}
  • 模拟实现具体过滤器
public class FirstFilter implements Filter  
{  
    @Override  
    public void doFilter(Request request, Response response, FilterChain filterChain) {  
        System.out.println("过滤器1 前置处理");  
//        先执行所有request再倒叙执行所有response  
        filterChain.doFilter(request,response);  
        System.out.println("过滤器1 后置处理");  
    }  
}
public class SecondFilter implements Filter  
{  
    @Override  
    public void doFilter(Request request, Response response, FilterChain filterChain) {  
        System.out.println("过滤器2 前置处理");  
//        先执行所有request再倒叙执行所有response  
        filterChain.doFilter(request,response);  
        System.out.println("过滤器2 后置处理");  
    }  
}
  • 模拟实现过滤器链FilterChain
public class FilterChain  
{  
    private List<Filter> filters = new ArrayList<>();  
    private int index = 0;  
//    链式调用  
    public FilterChain addFilter(Filter filter){  
        this.filters.add(filter);  
        return this;    }  
    public void doFilter(Request request, Response response)  
    {  
        if(index == filters.size()) return;  
        Filter filter = filters.get(index);  
        index ++;  
        filter.doFilter(request, response,this);  
    }  
}
  • 测试
public static void main(String[] args) {  
    Request request = null;  
    Response response = null;  
    FilterChain chain = new FilterChain();  
    chain.addFilter(new FirstFilter()).addFilter(new SecondFilter());  
    chain.doFilter(request, response);  
}
  • 结果
    ![[Pasted image 20230110223209.png]]
  • 类图![[Pasted image 20230110223302.png]]

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

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

相关文章

重学Attention

注意力机制对比RNN 主要解决了RNN无法并行&#xff0c;并且不能解决长序列依赖问题 所以为什么设计 Q K V这三个矩阵 一边来是让 K V的 首先通过Q 和 K点击计算Attention矩阵&#xff0c;这个矩阵表明的是V上每一个特征与Q的相关程度&#xff0c;相关程度高的&#xff0c;权重…

解剖一道有意思的指针题

这道指针题挺有意思的&#xff0c;将各级指针之间的联系联系起来&#xff0c;仔细分析会发现也不难&#xff0c;重在逻辑思维&#xff0c;做完将会加深你对指针的理解的&#xff0c;好好享受指针带来的乐趣吧&#xff01;&#xff01;&#xff01;结果是什么呢&#xff1f;//题…

FPGA 20个例程篇:19.OV7725摄像头实时采集送HDMI显示(三)

第七章 实战项目提升&#xff0c;完善简历 19.OV7725摄像头实时采集送HDMI显示&#xff08;三&#xff09; 在详细介绍过OV7725 CMOS Sensor的相关背景知识和如何初始化其内部寄存器达到输出预期视频流的目的后&#xff0c;就到了该例程的核心内容即把OV7725输出的视频流预先缓…

Zotero入门教程

文章目录一、生成Bibliography二、Zotero文献自动导入1. 为什么要使用SCI-HUB2. 如何自定义PDF解析器三、在Zotero中添加Extension四、文件存储位置的修改五、markdown笔记功能一、生成Bibliography 在 Document Preferences中点击“管理样式”&#xff0c;就可以在Zotero Styl…

我的周刊(第075期)

我的信息周刊&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。&#x1f3af; 项目elasticvue[1]基于 Vue 的 Elasticsearch 管理客户端…

Linux常见命令 16 - 权限管理命令 chown, chgrp, umask

目录 1. 改变文件/目录所有者 chown 2. 改变文件/目录的所属组 chgrp 3. 显示文件的缺省(默认)权限 umask [-S] 1. 改变文件/目录所有者 chown 改变文件权限使用chmod&#xff0c;只有root和当前文件拥有者可以更改&#xff0c;如果想要更改目录/文件的所有者&#xff0c…

MutationObserver的示例代码的使用(附示例代码)

MutationObserver的使用 首先先介绍一下MutationObserver的特点 1.MutationObserver的回调属于微队列 2.它会在触发指定 DOM 事件时&#xff0c;调用指定的回调函数&#xff0c;说白了就是用来检测DOM节点的 MutationObserver回调函数 参数 callback 一个回调函数&#xff0…

论文投稿指南——中文核心期刊推荐(环境科学 2)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

在甲骨文云容器实例(Container Instances)上部署Oracle Linux 7 Desktop

甲骨文云推出了容器实例&#xff0c;这是一项无服务器计算服务&#xff0c;可以即时运行容器&#xff0c;而无需管理任何服务器。 今天我们尝试一下通过容器实例部署Oracle Linux 7 Desktop。 创建容器实例 在甲骨文容器实例页面&#xff0c;单击"创建容器实例"&am…

分享150个PHP源码,总有一款适合您

PHP源码 分享150个PHP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 150个PHP源码下载链接&#xff1a;https://pan.baidu.com/s/1PWajFunhPFyoNFGc6F4qSQ?pwd0sq5 提取码&#…

Linux rm命令详解,Linux删除文件目录

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 rm 命令一、常用操作1. 删除文件2. 删除目录二、其他操作作用&#xff1a;删除文件或目录 参数&#xff1a; -f 直接删除&#xff0c…

steam/csgo搬砖项目真的假的?

本文全文干货分享&#xff0c;如果你想通过steam搬砖做副业赚钱&#xff0c;看这一篇就够了&#xff01; 这个项目是什么意思&#xff1f; 是不是你也很好奇这个玩法&#xff1f;我们先看下我们自己的数据&#xff0c;再来解释一下我们怎么赚的钱 一、项目原理 利用steam平台…

【Spring5源码学习】Spring基础介绍及调试环境搭建

Spring 是一款用于简化企业级 Java 应用开发的分层开源框架&#xff0c;有着强大的扩展和融合能力&#xff0c;它善于整合各种单层框架并建立起完整的体系&#xff0c;能高效统一的构造可提供企业级服务的应用系统。 1、Spring 概述 Spring Framework 是一个分层非常清晰并且依…

[C++]深复制与浅复制

深复制与浅复制 C中&#xff0c;默认的复制构造函数只能实现浅复制。 浅复制指的是在对象复制前&#xff0c;只对对象中的数据成员进行简单的复制 大多数情况下"浅复制"已经能很好的工作了&#xff0c;但是当类的数据成员中有指针类型时&#xff0c;浅复制只会复制指…

Gulp.Task 正解

gulp task 实现过程 今天从源码的角度分析下 gulp 中 task 的实现过程。多个 task 是如何执行&#xff1f;&#xff1f;&#xff1f; 等等 gulp 插件分布图 其实通过上述截图可以看到&#xff0c;其实整个 gulp 内部什么逻辑都没有&#xff0c;都是由一个一个插件组成的。上述的…

Java多线程案例之单例模式(饿汉,懒汉)

目录 一、饿汉模式 二、懒汉模式 前言&#xff1a;单例模式是校招中最常见的设计模式之一。下面我们来谈谈其中的两个模式&#xff1a;懒汉&#xff0c;饿汉。 何为设计模式&#xff1f; 设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多…

《Linux性能优化实战》学习笔记 Day04

06 | 锁&#xff1a;如何根据业务场景选择合适的锁&#xff1f; 原文摘抄 当你无法判断锁住的代码会执行多久时&#xff0c;应该首选互斥锁&#xff0c;互斥锁是一种独占锁。 如果你能确定被锁住的代码执行时间很短&#xff0c;就应该用自旋锁取代互斥锁。 对于 99% 的线程…

工信部电子标准院:龙蜥操作系统获评“优秀”

近日&#xff0c;工信部中国电子技术标准化研究院公布第二批通过开源项目成熟度评估的开源项目名单&#xff0c;龙蜥操作系统&#xff08;Anolis OS&#xff09;凭借在生态构建、技术创新、应用落地等方面的成熟能力与卓越表现&#xff0c;顺利通过评估并获得优秀贰级&#xff…

简单说说什么是真的懂一道题了

昨天写了Richard的2022年一年级入学小结后&#xff0c;后台有读者问我怎么算真的懂一个知识点了&#xff0c;今天来简单说两句&#xff0c;大家都知道&#xff0c;求123…n的和&#xff0c;高斯的幼年成名作。Richard同学在上中班的时候&#xff0c;我就给他科普过高大神的事迹…

2023牛客寒假算法基础集训营3 -- E-公平守望的灯塔(向量 简单几何)

题目如下&#xff1a; 示例1 输入 1 0 0 1输出 0 0说明 输出1 1也是可以的。 思路 or 题解&#xff1a; 我们可以迅速找到 CCC 有两个位置满足题意&#xff0c;但 CCC 的坐标不一定是整数&#xff0c;我们需要 checkcheckcheck MMM 是 ABABAB 的中点 我们可以求出来 AM→…