金三银四面试题(二十六):责任链模式知多少?

news2024/11/15 14:06:55

什么是责任链模式

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,旨在通过将请求的处理分布在一系列对象上,从而使得多个对象可以尝试处理同一个请求。这些对象被链接成一条链,每个对象都可以对请求进行处理,如果不能处理,则将请求传递给链中的下一个对象。

特点

  1. 请求的分发:请求在责任链中的每个对象上逐个传递,直到请求被处理或到达链的末端。

  2. 链上的对象:链上的每个对象都可以选择处理请求或将其传递给下一个对象。

  3. 解耦:请求的发送者和处理者之间的解耦。请求发送者不需要知道请求是由谁处理的。

  4. 可扩展性:可以动态地添加、移除或重新排列链上的对象,以调整请求的处理流程。

应用场景

  • 请求的处理需要经过多个对象,每个对象都可以对请求进行部分处理。
  • 请求的发送者和处理者之间的解耦。
  • 动态地添加或移除请求处理者。

优点

  • 松散耦合:请求的发送者和处理者之间的解耦。
  • 灵活性:可以动态地调整链中的对象以适应变化的需求。
  • 可维护性:链上的对象可以独立维护和扩展。

缺点

  • 链过长:如果责任链过长,可能导致请求处理效率低下。
  • 调试困难:由于请求在链中逐个传递,调试可能比较困难。

示例

SpringMVC 中的拦截器和Mybatis 中的插件机制,都是拦截器经典实现。

可以参照公司审批:我们在公司内部发起一个OA 审批流程,项目经理审批、部门经理审批。老板审批、人力审批。这就是生活中的责任链模式,每个角色的责任是不同。

下面是一个示例程序,展示了责任链模式在处理请假请求中的应用。程序定义了一个 Request 类表示请求,Handler 接口表示责任链中的处理者。然后通过三个具体的处理者类来处理请求。

// 请求类
class Request {
    private final int days;

    public Request(int days) {
        this.days = days;
    }

    public int getDays() {
        return days;
    }
}

// 处理者接口
interface Handler {
    void setNextHandler(Handler nextHandler);
    void handleRequest(Request request);
}

// 具体处理者类:主管
class SupervisorHandler implements Handler {
    private Handler nextHandler;

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

    @Override
    public void handleRequest(Request request) {
        if (request.getDays() <= 3) {
            System.out.println("Supervisor approved the leave request for " + request.getDays() + " days.");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        } else {
            System.out.println("Leave request for " + request.getDays() + " days is denied.");
        }
    }
}

// 具体处理者类:经理
class ManagerHandler implements Handler {
    private Handler nextHandler;

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

    @Override
    public void handleRequest(Request request) {
        if (request.getDays() <= 7) {
            System.out.println("Manager approved the leave request for " + request.getDays() + " days.");
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        } else {
            System.out.println("Leave request for " + request.getDays() + " days is denied.");
        }
    }
}

// 具体处理者类:总监
class DirectorHandler implements Handler {
    @Override
    public void setNextHandler(Handler nextHandler) {
        // 总监通常是责任链的末端,不需要设置下一个处理者
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getDays() <= 14) {
            System.out.println("Director approved the leave request for " + request.getDays() + " days.");
        } else {
            System.out.println("Leave request for " + request.getDays() + " days is denied.");
        }
    }
}

// 客户端代码
public class ChainOfResponsibilityDemo {
    public static void main(String[] args) {
        // 创建责任链
        Handler supervisor = new SupervisorHandler();
        Handler manager = new ManagerHandler();
        Handler director = new DirectorHandler();

        // 设置责任链的顺序
        supervisor.setNextHandler(manager);
        manager.setNextHandler(director);

        // 创建请求
        Request request1 = new Request(2);
        Request request2 = new Request(5);
        Request request3 = new Request(12);
        Request request4 = new Request(20);

        // 处理请求
        supervisor.handleRequest(request1);  // 主管处理
        supervisor.handleRequest(request2);  // 经理处理
        supervisor.handleRequest(request3);  // 总监处理
        supervisor.handleRequest(request4);  // 请求被拒绝
    }
}

我们定义了一个 Request 类表示请求,包含请假的天数。Handler 是责任链中的处理者接口,定义了 setNextHandlerhandleRequest 方法。三个具体的处理者类 SupervisorHandlerManagerHandlerDirectorHandler 分别代表主管、经理和总监,每个处理者都有不同的权限范围。如果当前处理者不能处理请求,就将请求传递给链中的下一个处理者。客户端创建请求并将其传递给责任链,由链中的处理者逐个处理请求。

在这里插入图片描述

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

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

相关文章

stm32——OLED篇

技术笔记&#xff01; 一、OLED显示屏介绍&#xff08;了解&#xff09; 1. OLED显示屏简介 二、OLED驱动原理&#xff08;熟悉&#xff09; 1. 驱动OLED驱动芯片的步骤 2. SSD1306工作时序 三、OLED驱动芯片简介&#xff08;掌握&#xff09; 1. 常用SSD1306指令 2. …

专业130+总分400+哈尔滨工程大学810信号与系统考研哈工程水声电子信息通信工程,真题,大纲,参考书。

毕业设计刚搞完&#xff0c;总结一下去年考研的复习经历&#xff0c;希望对大家复习有帮助&#xff0c;考研专业课810信号与系统130总分400&#xff0c;如愿上岸哈工程水声。专业课&#xff1a;130 哈工程水声院810专业课信号与系统难度适中&#xff0c;目前数一难度很高&…

【C语言/Python】嵌入式常用数据滤波处理:卡尔曼滤波器的简易实现方式(Kalman Filter)

【C语言/Python】嵌入式常用数据滤波处理&#xff1a;卡尔曼滤波器的简易实现方式&#xff08;Kalman Filter&#xff09; 文章目录 卡尔曼滤波卡尔曼滤波公式卡尔曼滤波数据处理效果C语言的卡尔曼滤波实现附录&#xff1a;压缩字符串、大小端格式转换压缩字符串浮点数压缩Pack…

TCP三次握手四次挥手 UDP

TCP是面向链接的协议&#xff0c;而UDP是无连接的协议 TCP的三次握手 三次传输过程是纯粹的不涉及数据&#xff0c;三次握手的几个数据包中不包含数据内容。它的应用层&#xff0c;数据部分是空的&#xff0c;只是TCP实现会话建立&#xff0c;点到点的连接 TCP的四次挥手 第四…

JVM堆内存分析

jmap工具查看堆内存 jmap:全称JVM Memory Map 是一个可以输出所有内存中对象的工具&#xff0c;可以将JVM中的heap&#xff08;堆&#xff09;&#xff0c;以二进制输出成文本&#xff0c;打印出Java进程对应的内存 找到pid jmap -heap 19792 Attaching to process ID 19792…

贪心算法-----柠檬水找零

今日题目&#xff1a;leetcode860 题目链接&#xff1a;点击跳转题目 分析&#xff1a; 顾客只会给三种面值&#xff1a;5、10、20&#xff0c;先分类讨论 当收到5美元时&#xff1a;不用找零&#xff0c;面值5张数1当收到10美元时&#xff1a;找零5美元&#xff0c;面值5张数…

bevformer详解(1):论文介绍

3D 视觉感知任务,包括基于多摄像头的3D检测和地图分割对于自动驾驶系统至关重要。本文提出了一种名为BEVFormer的新框架,它通过使用空间和时间的Transformer 学习统一的BEV表示来支持多个自动驾驶感知任务。简而言之,BEVFormer通过预定义的网格形式的Bev Query与空间和时间空…

icap对flash的在线升级

文章目录 一、icap原语介绍&#xff08;针对 S6 系列的 ICap&#xff09;&#xff0c;之后可以拓展到A7、K7当中去二、程序1设计2.1信号结构框图2.2 icap_delay设计2.3 icap_ctrl设计&#xff08;可以当模板使用&#xff0c;之后修改关键参数即可&#xff09; 三、程序2设计四、…

如何同时或者按顺序间隔启动多个程序

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 1、打开工具&#xff0c;切换到定时器模块&#xff0c;快捷键&#xff1a;Ctrl3 2、新建一个定时器&#xff0c;我这里演示同时打开多个程序&#xff08;比…

在shell程序里如何从文件中获取第n行

问题&#xff1a; 有没有一种“规范”的方式来做到这一点&#xff1f;我一直在使用 head -n | tail -1&#xff0c;它可以做到这一点&#xff0c;但我一直想知道是否有一个Bash工具&#xff0c;专门从文件中提取一行(或一段行)。 所谓“规范”&#xff0c;我指的是一个主要功…

HTML五彩缤纷的爱心

写在前面 小编准备了一个五彩缤纷的爱心&#xff0c;送给各位小美女们~ 在桌面创建一个.txt文本文件&#xff0c;把代码复制进去&#xff0c;将后缀.txt改为.html&#xff0c;然后就可以双击运行啦&#xff01; HTML简介 HTML&#xff08;超文本标记语言&#xff09;是一种…

Stable Diffusion是什么?

目录 一、Stable Diffusion是什么&#xff1f; 二、Stable Diffusion的基本原理 三、Stable Diffusion有哪些运用领域&#xff1f; 一、Stable Diffusion是什么&#xff1f; Stable Diffusion是一个先进的人工智能图像生成模型&#xff0c;它能够根据文本描述创造出高质量的图…

VMware安装centos7教程

文章目录 1、centos7的ios镜像下载2、CentOS7安装3、Centos配置 其他教程&#xff1a; 1、VMware Workstation 16 Pro安装教程 2、VMwarePro16安装Ubuntu16.04图文教程 1、centos7的ios镜像下载 官网&#xff1a;https://vault.centos.org/ 阿里云&#xff1a;https://develo…

Idea入门:一分钟创建一个Java工程

一&#xff0c;新建一个Java工程 1&#xff0c;启动Idea后&#xff0c;选择 [New Project] 2&#xff0c;完善工程信息 填写工程名称&#xff0c;根据实际用途取有意义的英文名称选择Java语言&#xff0c;可以看到还支持Kotlin、Javascript等语言选择包管理和项目构建工具Mav…

新闻资讯微信小程序开发后端+php【附源码,文档说明】

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

2024最新版JavaScript逆向爬虫教程-------基础篇之无限debugger的原理与绕过

目录 一、无限debugger的原理与绕过1.1 案例介绍1.2 实现原理1.3 绕过debugger方法1.3.1 禁用所有断点1.3.2 禁用局部断点1.3.3 替换文件1.3.4 函数置空与hook 二、补充2.1 改写JavaScript文件2.2 浏览器开发者工具中出现的VM开头的JS文件是什么&#xff1f; 三、实战 一、无限…

Java构造方法详解

在Java方法内部定义一个局部变量时&#xff0c;必须要初始化&#xff0c;否则就会编译失败&#xff0c;如下&#xff1a; 要让上述代码通过编译&#xff0c;只需在使用a之前给a赋一个初始值即可 如果是对象&#xff1a;下面用一个日期类演示 我们没有给年月日赋值&#xff0c;…

laravel8 导入 excel常见问题

上传xls 或 xlsx 文件后&#xff0c;文件解析为 zip 格式&#xff0c;输入正常情况&#xff0c;不影响解析 里面的内容 遇到解析内容&#xff0c;解析为空的情况&#xff0c;可能是 因为excel 存在多个 Sheet1 造成&#xff0c;服务器不能解析一个 Sheet1 的情况&#xff0…

阿里开源编程大模型 CodeQwen1.5:64K92编程语言,Code和SQL编程,评测接近GPT-4-Turbo

前言 阿里巴巴最近发布的CodeQwen1.5模型标志着其在编程语言模型领域的一次重大突破。这款开源模型不仅支持高达92种编程语言和64K的上下文长度&#xff0c;而且在多项性能评测中显示出接近或超过当前行业领导者GPT-4-Turbo的能力。 Huggingface模型下载&#xff1a;https://h…

# ERROR: node with name “rabbit“ already running on “MS-ITALIJUXHAMJ“ 解决方案

ERROR: node with name “rabbit” already running on “MS-ITALIJUXHAMJ” 解决方案 一、问题描述&#xff1a; 1、启动 rabbitmq-server.bat 服务时&#xff0c;出错 Error 2、查询 rabbitmqctl status 状态时&#xff0c;出错 Error 3、停止 rabbitmqctl stop 服务时&a…