JAVA设计模式--行为型模式--职责链模式

news2024/12/24 0:19:18

1.责任链模式(Chain of Responsibility Pattern)

1.1介绍

为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

1.2意图:

避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

1.3主要解决:

职责链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

1.4何时使用:

在处理消息的时候以过滤很多道。
在这里插入图片描述

1.5如何解决:

拦截的类都实现统一接口。

1.6关键代码:

Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。

1.7应用实例:

1、红楼梦中的"击鼓传花"。 2、JS 中的事件冒泡。 3、JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。

1.8优点:

1、降低耦合度。它将请求的发送者和接收者解耦。 2、简化了对象。使得对象不需要知道链的结构。 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 4、增加新的请求处理类很方便。

1.9缺点:

1、不能保证请求一定被接收。 2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。 3、可能不容易观察运行时的特征,有碍于除错。

1.10使用场景:

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。

1.11注意事项:

在 JAVA WEB 中遇到很多应用。

1.12 实现

我们创建抽象类 AbstractLogger,带有详细的日志记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。
在这里插入图片描述
创建抽象的记录器类。

public abstract class AbstractLogger {
   public static int INFO = 1;
   public static int DEBUG = 2;
   public static int ERROR = 3;
 
   protected int level;
 
   //责任链中的下一个元素
   protected AbstractLogger nextLogger;
 
   public void setNextLogger(AbstractLogger nextLogger){
      this.nextLogger = nextLogger;
   }
 
   public void logMessage(int level, String message){
      if(this.level <= level){
         write(message);
      }
      if(nextLogger !=null){
         nextLogger.logMessage(level, message);
      }
   }
 
   abstract protected void write(String message);
   
}

创建扩展了该记录器类的实体类。

public class ConsoleLogger extends AbstractLogger {
 
   public ConsoleLogger(int level){
      this.level = level;
   }
 
   @Override
   protected void write(String message) {    
      System.out.println("Standard Console::Logger: " + message);
   }
}
public class ErrorLogger extends AbstractLogger {
 
   public ErrorLogger(int level){
      this.level = level;
   }
 
   @Override
   protected void write(String message) {    
      System.out.println("Error Console::Logger: " + message);
   }
}
public class FileLogger extends AbstractLogger {
 
   public FileLogger(int level){
      this.level = level;
   }
 
   @Override
   protected void write(String message) {    
      System.out.println("File::Logger: " + message);
   }
}

创建不同类型的记录器。赋予它们不同的错误级别,并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分。

public class ChainPatternDemo {
   
   private static AbstractLogger getChainOfLoggers(){
 
      AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
      AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
      AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
 
      errorLogger.setNextLogger(fileLogger);
      fileLogger.setNextLogger(consoleLogger);
 
      return errorLogger;  
   }
 
   public static void main(String[] args) {
      AbstractLogger loggerChain = getChainOfLoggers();
 
      loggerChain.logMessage(AbstractLogger.INFO, "This is an information.");
 
      loggerChain.logMessage(AbstractLogger.DEBUG, 
         "This is a debug level information.");
 
      loggerChain.logMessage(AbstractLogger.ERROR, 
         "This is an error information.");
   }
}

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

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

相关文章

C语言文件操作(一文带你吃透文件各种操作)

文章目录 一、为什么要使用文件 二、什么是文件 2、1 程序文件 2、2 数据文件 2、3 文件名 三、文件的打开关闭及读写操作 3、1 文件指针 3、2 文件的打开和关闭操作 3、3 文件的读写函数详解 3、3、1 fgetc、fputc函数详解 3、3、2 fgets、fputs函数详解 3、3、3 fscanf、fpri…

神经网络介绍-激活函数、参数初始化、模型的搭建

目录1、深度学习了解1.1 深度学习简介1.2 神经网络2、神经网络的工作流程2.1 激活函数2.1.1 Sigmoid/Logistics函数2.1.2 tanh&#xff08;双曲正切曲线&#xff09;2.1.3 RELU2.1.4 Leaky Relu2.1.5 SoftMax2.1.6 其他激活函数2.2 参数初始化2.2.1 随机初始化2.2.2 标准初始化…

【博客585】ipvs场景下dummy网卡的作用

linux ipvs模式下dummy网卡的作用 1、场景&#xff1a; 在使用ipvs来实现vip的负载均衡的时候&#xff0c;有时我们会在linux中创建一块dummy网卡&#xff0c;并在网卡上绑上vip 2、场景示例&#xff1a;k8s kube-proxy组件的ipvs模式 kube-proxy在ipvs模式下生成了一块kub…

iperf工具源码下载、编译、编译报错解决、以及测试网络带宽

1、iperf源码下载 (1)源码下载地址&#xff1a;https://iperf.fr/iperf-download.php; (2)有的版本源码下载下来并不能直接编译成功&#xff0c;可能会报缺少头文件或者编译选项的错误&#xff0c;要么去解决这些错误&#xff0c;要么换个版本再试一下&#xff1b; (3)在我的环…

Linux学习【教程+实操】【超基础】

链接:资料提取码&#xff1a;6klp 今日内容Linux简介Linux安装网卡设置安装SSH连接工具Linux和Windows目录结构对比Linux常用命令Linux命令初体验文件目录操作命令拷贝移动命令打包压缩命令文本编辑命令查找命令Linux软件安装软件安装方式安装jdk&#xff08;采用二进制发布包…

mysql索引字段设计

表字段数量与row大小限制可以参考官方文档 https://dev.mysql.com/doc/refman/8.0/en/column-count-limit.html#column-count-limits 复合索引 参考&#xff1a;https://dev.mysql.com/doc/refman/8.0/en/innodb-limits.html 数量限制 一个复合索引最多可以包含16个列&…

微信小程序--自定义组件

组件的创建与引用 1.创建组件 在项目的根目录中&#xff0c;鼠标右键&#xff0c;创建 components -> test 文件夹 在新建的components -> test文件夹上&#xff0c;鼠标右键&#xff0c;点击“新建Component" 键入组件的名称之后回车&#xff0c;会自动生成组件对…

C语言进阶(9)——C语言文件操作

本章重点 为什么使用文件什么是文件文件的打开和关闭文件的顺序读写文件的随机读写文本文件和二进制文件文件读取结束的判定文件缓冲区 文章目录本章重点1.为什么使用文件2.什么是文件2.1程序文件2.2数据文件2.3文件名3.文件打开和关闭3.1 文件指针3.2文件的打开和关闭4. 文件…

【蓝桥杯嵌入式】第十一届蓝桥杯嵌入式省赛(第二场)程序设计试题及其题解

题目再现 题目分析 通过阅读本届试题可知&#xff0c;其功能比较单一&#xff0c;除了试题中常客——LED、LCD、按键三巨头外&#xff0c;还包含了定时器的PWM以及ADC读取这两个部分&#xff0c;考察的重点在于对定时器产生PWM的应用以及如何修改PWM的占空比&#xff0c;完全消…

MPU-6000(6050)介绍

MPU-6000&#xff08;6050&#xff09;简介MPU-60X0是全球首例9 轴运动处理传感器。它集成了3 轴MEMS陀螺仪&#xff0c;3 轴MEMS加速度计&#xff0c;以及一个可扩展的数字运动处理器DMP&#xff08;DigitalMotion Processor&#xff09;&#xff0c;可用I2C接口连接一个数字传…

react PureComponent

这个 其实和我之前写的文章react组件优化&#xff0c;当父组件数据变化与子组件无关时&#xff0c;控制子组件不重新渲染实现的东西是一样的 只是用了一种更简洁的方式 我们还是重新来一次 创建一个react项目 然后 创建一个子组件 我这里就直接叫 subset.jsx 参考代码如下 i…

ADAM: A METHOD FOR STOCHASTIC OPTIMIZATION

核心 Adam: 一种基低阶矩的自适应估计的随机目标函数的一阶梯度优化算法&#xff0c;该方法实现简单**&#xff0c;计算效率高&#xff0c;内存需求很少**&#xff0c;对梯度的对角线重新缩放不变&#xff0c;并且非常适合于在数据或参数方面较大问题&#xff0c;该方法也适用…

ADI demo PS工程的编译-以adrv9371x_zc706为例子

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 ADI demo PS工程的编译-以adrv9371x_zc706为例子前言VITIS建工程总结前言 接《ADI demo PL工程的编译-以adrv9371x_zc706为例子之使用Cygwin》这篇。导出XSA文件&#xff0c…

VMware虚拟机搭建安装MacOS13及开发环境搭建

文章目录前言准备工作&#xff1a;安装虚拟机及MacOS系统1.安装VMware 虚拟机2. 运行解锁工具3. 安装macOS 134. 配置网络5. 安装VMware tools开发环境1. 安装xcode2. 安装HbuilderX前言 终于把macOS13虚拟机安装好了&#xff0c;比起上次安装macOS10,这次走了很多弯路。 先说…

108. 将有序数组转换为二叉搜索树

108. 将有序数组转换为二叉搜索树 难度简单1214 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉树。 示例 1&…

春节期间商城如何做好运营

有经验的商家都知道&#xff0c;春节对于店铺来说&#xff0c;这是一个全新的起点&#xff0c;所以商家们一定要抓住新年这个过渡期的时机。那么在春节期间的运营该如何做呢&#xff1f; 首先看看春节期间会有的几个问题&#xff1a; 推广竞争会比较小&#xff0c;在这个时间…

git使用日常问题记录【按日期频繁记录,欢迎收藏】

git系列文章 文章目录2023.1.14 将gitee仓库转移到github遇到的问题1-1 add到暂存区&#xff0c;commit到仓库之后&#xff0c;不想push了&#xff1f;&#xff1f;&#xff1f;1-2 git push大文件失败解决1-3 上传多余文件&#xff0c;如何从远端仓库中删除2023.1.151-1 githu…

销售管理系统 | 数据库课设

文章目录前言项目介绍E-R图表结构系统总体框架搭建项目环境介绍创建网站主页连接数据库注册功能登录功能管理员登录功能注销登录功能个人信息后台管理查看供应商名单删除功能修改功能登记货物信息功能购买商品功能总源码教训总结前言 为了期末的数据库课设&#xff0c;这是最初…

【C++】STL - Stack - Queue - PriorityQueue使用和模拟实现

&#x1f431;作者&#xff1a;傻响 &#x1f431;专栏&#xff1a;《数据结构_STL》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 目录 栈 Stack介绍 模拟实现 队列 Queue介绍 常用的函数接口介绍 模拟实现 优先级队列 Priority…

【docker18】docker容器之CAdvisor+InfluxDB+Granfana

1.原生命令 1.1操作 命令&#xff1a; docke stats 1.2问题 通过docker stats命令可以很方便的看到当前宿主机上所有容器的CPU&#xff0c;内存以及网络流量控制等数据&#xff0c;一般的小公司够用了。 但是&#xff0c;docker stats统计结果只能是当前宿主机的全部容器&am…