【设计模式】责任链模式

news2024/11/16 9:27:21

【设计模式】责任链模式

文章目录

  • 【设计模式】责任链模式
    • 一:责任链模式概述
    • 二:责任链模式结构
    • 三:责任链模式案例实现
    • 四:优缺点
    • 五:责任链模式实战

一:责任链模式概述

在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。例如,公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增加了难度。这样的例子还有很多,如找领导出差报销、生活中的“击鼓传花”游戏等。

定义:

  • 责任链模式为请求创建一个接收者对象链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把请求传给下一个接收者,依此类推
  • 责任链模式避免了请求的发送者和接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连成一条链,并且沿着这条链传递请求,直到有对象处理它为止

二:责任链模式结构

对象定义

  • Handler(抽象处理者) :

    定义一个处理请求的接口,提供对后续处理者的引用

  • ConcreteHandler(具体处理者) :

    抽象处理者的子类,处理用户请求,可选将请求处理掉还是传给下家;在具体处理者中可以访问链中下一个对象,以便请求的转发

image-20221217011324800

三:责任链模式案例实现

  • 抽象处理者
public abstract class Handler {

    protected Handler nextHandler; // 下一个责任链成员

    public Handler getNextHandler() {
        return nextHandler;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    // 处理传递过来的时间
    public abstract void handleMessage(int type);
}
  • 具体处理者

    在当前处理者对象无法处理时,将执行权传给下一个处理者对象

public class ConcreteHandler1 extends Handler {

    @Override
    public void handleMessage(int type) {
        if (type == 1 || type == 3) {
            System.out.println("ConcreteHandler1解决了问题!");
        } else {
            System.out.println("ConcreteHandler1解决不了问题......");
            if (nextHandler != null) {
                nextHandler.handleMessage(type);
            } else {
                System.out.println("没有人能处理这个消息");
            }
        }
    }
}

public class ConcreteHandler2 extends Handler {

    @Override
    public void handleMessage(int type) {
        if (type == 2 || type == 5) {
            System.out.println("ConcreteHandler2解决了问题!");
        } else {
            System.out.println("ConcreteHandler2解决不了问题......");
            if (nextHandler != null) {
                nextHandler.handleMessage(type);
            } else {
                System.out.println("没有人能处理这个消息");
            }
        }
    }
}

public class ConcreteHandler3 extends Handler {

    @Override
    public void handleMessage(int type) {
        if (type == 4 || type == 6) {
            System.out.println("ConcreteHandler3解决了问题!");
        } else {
            System.out.println("ConcreteHandler3解决不了问题......");
            if (nextHandler != null) {
                nextHandler.handleMessage(type);
            } else {
                System.out.println("没有人能处理这个消息");
            }
        }
    }
}
  • Client*客户端调用
// 初始化责任链:handler1 -> handler2 -> handler3
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        Handler handler3 = new ConcreteHandler3();
        handler2.setNextHandler(handler3);
        handler1.setNextHandler(handler2);
        // 处理事件
        System.out.println("--------------Message1");
        handler1.handleMessage(1);
        System.out.println("--------------Message2");
        handler1.handleMessage(2);
        System.out.println("--------------Message3");
        handler1.handleMessage(4);
        System.out.println("--------------Message4");
        handler1.handleMessage(7);

从上述模式可以知道,当我们需要多个 if/else 做逻辑判断的时候,可以引入,从而提高代码可维护性

四:优缺点

1、优点:

  • 降低了对象之间的耦合度

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

  • 增强了系统的可扩展性

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

  • 增强了给对象指派职责的灵活性

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

  • 责任链简化了对象之间的连接

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

  • 责任分担

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

2、缺点:

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

五:责任链模式实战

  • 对购物车价格进行渲染

image-20221217011838782

  • 根据渲染步骤,渲染购物车信息

image-20221217011907693

  • 渲染一笔交易

image-20221217011954921

image-20221217012026948

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

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

相关文章

Jmeter(二十一):jmeter导入和导出接口的处理

JMeter测试导入接口 利用Jmeter测试上传文件,首先可根据接口文档或者fiddler抓包分析文件上传的接口;如下图: 以下是我通过fiddler所截取的文件上传的接口 1、填写导入接口的信息 查看文件上传栏下的填写信息: 文件名称&#xf…

【图像分割】多种阈值图像分割(带面板)【含GUI Matlab源码 733期】

⛄一、图像分割简介 理论知识参考:【基础教程】基于matlab图像处理图像分割【含Matlab源码 191期】 ⛄二、部分源代码 function varargout yuzhifenge(varargin) % YUZHIFENGE MATLAB code for yuzhifenge.fig % YUZHIFENGE, by itself, creates a new YUZHIFEN…

【Redis】缓存问题

用户数据一般都是存储在数据库中,数据库则落在磁盘上。而磁盘的I/O速度是计算机中最慢的硬件。 当用户的访问量在某一个时间段突然上升,数据库就很容易崩溃。为了避免用户直接访问数据库,所以会使用缓存数据库(Redis)作为缓冲层。 Redis 是内…

DIY NAS服务器之OMV 5.6入坑指南(二)- 安装omv-extras插件

DIY NAS服务器之OMV 5.6入坑指南(一)-openmediavalut 5.6安装 前面我们已经安装好了OMV5.6了。 接下来就是建设我们的OMV系统了。 首先第一步,我们开启社区插件omv-extras: 通过如下url把插件安装文件 下载到电脑本地&#xff0c…

Mysql分布式锁(二)直接用一条sql语句来实现原子性

文章目录一、直接用更新的sql实现1. 场景描述2. 修改sqlStockMapperStockService3. 重新测试二、问题1. 锁范围问题:行级锁 表级锁2. 若逻辑太复杂,一个sql无法实现4. 无法监控库存变化前后的状态一、直接用更新的sql实现 1. 场景描述 之前的deduct()方…

DevOps实战系列【第十三章】:流水线应用工具Blue Ocean使用

个人亲自录制全套DevOps系列实战教程 :手把手教你玩转DevOps全栈技术 BlueOcean图形化工具 可以通过插件的方式安装到jenkins,搜索“Blue Ocean”,安装后重启即可。 由于兼容问题,BlueOcean依赖的插件有些是失败的,我…

实际生产中使用Oracle的小问题及解决方法记录:ORA-00911,ORA-12514,ORA-28547

背景 在上次安装并初步测试 Oracle 后Oracle 11g安装使用、备份恢复并与SpringBoot集成,在实际生产中使用 Oracle 时又遇到几个小问题: ORA-00911 , ORA-12514 , ORA-28547 。下面分别列出这几个问题的解决方法。 Note&#xff…

DCBC路由模式配置端口映射

DCBC路由模式配置端口映射 拓扑搭建 前提:使用DCBC、CS6200、两台PC机:一台用户配置IP另一台用于测试端口映射,外网环境使用192.168.19.0/24网段 网段划分 全网互通 1.DCBC对应工作模式配置 对应接口配置 配置静态路由两条,一条…

ArcGIS And ENVI:如何进行植被指数的提取并制作成专题地图?

目录 01 目的 02 操作步骤 2.1 在ENVI加载tm_860516.img文件 2.2 进行NDVI指数的计算 2.3 使用ArcGIS对NDVI植被指数提取图进行专题制作 2.3.1 加载NDVI植被指数提取图 2.3.2 对NDVI植被指数提取图进行重分类 2.3.3 布局视图下的NDVI植被指数的相关编辑 03 实验结果 01 目的 对…

Iterated function

In mathematics, an iterated function is a function X → X (that is, a function from some set X to itself) which is obtained by composing another function f : X → X with itself a certain number of times. The process of repeatedly applying the same function…

【数据结构与算法 - 数据结构基础】什么是数据结构?

【数据结构与算法 - 数据结构基础】什么是数据结构? 文章目录【数据结构与算法 - 数据结构基础】什么是数据结构?1 数据结构包含的三个方面1.1 数据的逻辑结构1.1.1 线性结构数组【Array】链表【LinkedList】栈【Stack】队列【Queue】1.1.2 树结构【Tree…

【生信】初探基因定位和全基因组关联分析

初探QTL和GWAS 文章目录初探QTL和GWAS实验目的实验内容实验题目第一题:玉米MAGIC群体的QTL分析第二题:TASSEL自带数据集的关联分析实验过程玉米MAGIC群体的QTL分析① 包含的数据② 绘制LOD曲线株高对应的QTLTASSEL自带数据集的关联分析TASSEL简介实际操作…

Docker ( 一 ) 基本概念及安装

1.Docker是什么? Docker 是一个开源的应用容器引擎, 可以简化理解实现应用与运行环境分离. Docker 其中包括,镜像、容器、仓库等概念,目的就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的产品&#xff08…

Android 进阶——性能优化之电量优化全攻略及实战小结(一)

文章大纲引言一、偷懒至上的原则二、低电耗模式1、低电耗模式概述2、低电耗模式限制3、适配适应低电耗模式三、应用待机模式对其他用例的支持引言 电池续航时间是移动用户体验中最重要的一个方面。没电的设备完全无法使用。因此,对于应用来说,尽可能地考…

数据库拆分4--sharding-jdbc-spring-boot-starter自动装配启动过程

学习一下springboot是如何整合sharding-jdbc的。 添加依赖以后 <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version> </dependency…

Java8之JMX与MBean

参考文章&#xff1a; 《JMX超详细解读》 《JMX》 写在开头&#xff1a;本文为学习后的总结&#xff0c;可能有不到位的地方&#xff0c;错误的地方&#xff0c;欢迎各位指正。 在学习tomcat源码架构的时候了解到其中使用了JMX来实现一些管理工作&#xff0c;于是便整理了这篇…

Linux systemd-run unit封装CGroup资源进行任务运行

Linux systemd-run 封装资源使用 序 之前我们讲了关于 systemctl 对各种服务或者说是 unit 进行了讲解&#xff0c;也讲了怎么创建一个 unit&#xff0c;进行相关配置或者依赖设置等等。在使用 systemctl status xxx 时&#xff0c;我们可以发现对应的资源使用情况&#xff0…

JSTL标签库 | 深入解析JSTL标签库

目录 一&#xff1a;深入解析JSTL标签库 1、什么是JSTL标签库 2、使用JSTL标签库的步骤 3、JSTL标签的原理 4、jstl中的核心标签库core当中常用的标签 一&#xff1a;深入解析JSTL标签库 1、什么是JSTL标签库 ①Java Standard Tag Lib&#xff08;Java标准的标签库&am…

电脑文件不小心删除了怎么恢复 ? 删除的文件如何恢复文件?

如果误删电脑文件后&#xff0c;如何恢复文件&#xff1f; 电脑删除文件是很经常的事&#xff0c;为了电脑运行更快我们经常都会清理&#xff0c;但是有时候也会出现不小心删除重要文件的情况。如何恢复删除的文件&#xff1f;本文总结的2种常用方法可以帮助到你。 方法1、注册…

惠普CP1025 因转印离合器导致打印不全大片空白的问题

问题症状 自检只打印出一部分, 后面大部分都是空白. 如果是碳盒缺粉, 应该是均匀地浅或者空白, 如果是成像鼓的问题, 应该是从上到下成条状的不均匀, 这样显示一节后空白的情况是没见过, 上网查有类似的问题 惠普CP1025彩色激光打印机打印图像前半部有字后半部白纸惠普1025打印…