一个个顺序挨着来 - 责任链模式(Chain of Responsibility Pattern)

news2025/1/14 18:19:20

责任链模式(Chain of Responsibility Pattern)

  • 责任链模式(Chain of Responsibility Pattern)
    • 责任链模式(Chain of Responsibility Pattern)概述
      • 责任链结构图
      • 责任链模式概述
      • 责任链模式涉及的角色
    • talk is cheap, show you my code
    • 总结

责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理者链条传递,直到有一个处理者能够处理它为止。这种模式避免了请求发送者和接收者之间的耦合,并且可以动态地指定一组处理者来处理请求。每个处理者都包含对下一个处理者的引用,如果当前处理者不能处理请求,它会将请求转发给下一个处理者。

太抽象了,举个现实生活中的例子
生活中,我们可能会遇到需要报销的生活场景。但是报销的时候,每个人的报销权限不一样。比如金额比较小的时候,你的领导就可以帮你审批;但是如果金额超过了你领导的审核范围,你的领导可能就把报销的交给他的上一层领导处理;他的上一层领导如果能处理就处理,处理不了,就沿着审批链条再往上进行审批。

责任链模式(Chain of Responsibility Pattern)概述

责任链结构图

在这里插入图片描述

责任链模式概述

  • 定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
  • 目的:解耦请求的发送者与接收者,提供一个灵活的方式来处理请求,支持动态添加或移除处理逻辑。

责任链模式涉及的角色

  1. 抽象处理者(Handler):声明了所有具体处理者必须实现的方法,通常是handle()方法。此外,它还可能包含一个指向下一个处理者的引用。
public abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(String request);
}
  1. 具体处理者(ConcreteHandler):实现了Handler接口的具体类。
public class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("A".equals(request)) {
            System.out.println("Handled by ConcreteHandlerA");
        } else {
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}

public class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("B".equals(request)) {
            System.out.println("Handled by ConcreteHandlerB");
        } else {
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}
  1. 客户端(Client):客户端创建具体的处理者对象,并根据需要将它们链接起来形成一条责任链。然后,客户端将请求传递给链中的第一个处理者。
public class Client {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();

        // 构建责任链
        handlerA.setSuccessor(handlerB);

        // 发送请求
        handlerA.handleRequest("A"); // Handled by ConcreteHandlerA
        handlerA.handleRequest("B"); // Handled by ConcreteHandlerB
        handlerA.handleRequest("C"); // Not handled, no output or error
    }
}

talk is cheap, show you my code

我们还是利用本次要介绍的设计模式来实现我们给出的例子。

  1. 首先,我们定义一个ApprovalRequest类来表示审批请求:
public class ApprovalRequest {
    private double amount;
    private String description;
    private boolean isApproved = false;

    public ApprovalRequest(double amount, String description) {
        this.amount = amount;
        this.description = description;
    }

    public double getAmount() {
        return amount;
    }

    public String getDescription() {
        return description;
    }

    public boolean isApproved() {
        return isApproved;
    }

    public void setApproved(boolean approved) {
        isApproved = approved;
    }
}
  1. 接下来,我们定义一个Approver接口,所有审批者都将实现这个接口:
public interface Approver {
    void processRequest(ApprovalRequest request);
    Approver getNextApprover();
    void setNextApprover(Approver nextApprover);
}
  1. 我们为不同的审批级别创建具体的审批者类。例如,部门经理(DepartmentManager)、总监(Director)和CEO(ChiefExecutiveOfficer)
public class DepartmentManager implements Approver {
    private Approver nextApprover;
    private static final double LIMIT = 5000.0;

    public DepartmentManager() {
    }

    @Override
    public void processRequest(ApprovalRequest request) {
        if (request.getAmount() <= LIMIT) {
            System.out.println(request.getDescription() + " is approved by Department Manager.");
            request.setApproved(true);
        } else {
            if (nextApprover != null) {
                nextApprover.processRequest(request);
            } else {
                System.out.println(request.getDescription() + " was rejected.");
                request.setApproved(false);
            }
        }
    }

    @Override
    public Approver getNextApprover() {
        return nextApprover;
    }

    @Override
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}

public class Director implements Approver {
    private Approver nextApprover;
    private static final double LIMIT = 20000.0;

    // Similar methods as in DepartmentManager
    // ...
}

public class ChiefExecutiveOfficer implements Approver {
    private Approver nextApprover;

    // No limit for CEO, all requests will be approved or rejected here
    // Similar methods as in DepartmentManager and Director
    // ...
}
  1. 最后,我们可以编写一个客户端类来测试这个责任链:
public class Client {
    public static void main(String[] args) {
        ApprovalRequest request1 = new ApprovalRequest(4500, "Office supplies");
        ApprovalRequest request2 = new ApprovalRequest(12000, "New computer");
        ApprovalRequest request3 = new ApprovalRequest(25000, "Conference room renovation");

        Approver departmentManager = new DepartmentManager();
        Approver director = new Director();
        Approver ceo = new ChiefExecutiveOfficer();

        departmentManager.setNextApprover(director);
        director.setNextApprover(ceo);

        departmentManager.processRequest(request1);
        System.out.println("Request1 approved? " + request1.isApproved());

        departmentManager.processRequest(request2);
        System.out.println("Request2 approved? " + request2.isApproved());

        departmentManager.processRequest(request3);
        System.out.println("Request3 approved? " + request3.isApproved());
    }
}

在这个客户端类中,我们创建了三个审批请求,并设置了审批链。然后,我们依次处理这些请求,并打印出它们是否被批准。

总结

责任链可以帮助我们降低耦合度;增加灵活性;可以帮助我们更好地组织代码。我们上面实现地责任链模式是类似与拦截器的那种方式。责任链还可以设计为一些别的方式。责任链模式一般适用于日志记录;审批流程等等。

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

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

相关文章

.NET framework、Core和Standard都是什么?

对于这些概念一直没有深入去理解&#xff0c;以至于经过.net这几年的发展进化&#xff0c;概念越来越多&#xff0c;越来越梳理不容易理解了。内心深处存在思想上的懒惰&#xff0c;以为自己专注于Unity开发就好&#xff0c;这些并不属于核心范畴&#xff0c;所以对这些概念总是…

【Java回顾】Day5 并发基础|并发关键字|JUC全局观|JUC原子类

JUC全称java.util.concurrent 处理并发的工具包(线程管理、同步、协调) 一.并发基础 多线程要解决什么问题&#xff1f;本质是什么&#xff1f; CPU、内存、I/O的速度是有极大差异的&#xff0c;为了合理利用CPU的高性能&#xff0c;平衡三者的速度差异&#xff0c;解决办法…

android framework.jar 在应用中使用

在开发APP中&#xff0c;有时会使用系统提供的framework.jar 来替代 android.jar, 在gradle中配置如下&#xff1a; 放置framework.jar 依赖配置 3 优先级配置 gradle.projectsEvaluated {tasks.withType(JavaCompile) {Set<File> fileSet options.bootstrapClasspat…

CHAIN OF RESPONSIBILITY(职责链)—对象行为型模式

1. 意图 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 2. 动机 考虑一个图形用户界面中的上下文有关的帮助机制。用户在界面的任一部分…

Java高频面试之SE-11

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java中是引用传递还是值传递&#xff1f; 在 Java 中&#xff0c;方法参数传递是通过 值传递 的方式实现的&#xff0c;但这可能会引起一…

VsCode对Arduino的开发配置

ps&#xff1a;我的情况是在对esp32进行编译、烧录时&#xff0c;找不到按钮&#xff0c;无法识别Arduino文件&#xff0c;适合已经有ini文件的情况。 1.在vscode中安装拓展 2.打开设置&#xff0c;点击右上角&#xff0c;转到settings.json文件 3.复制以下代码并保存 {"…

Apache Hop从入门到精通 第一课 揭开Apache Hop神秘面纱

一、Apache Hop是什么&#xff1f; 1、Apache Hop&#xff0c;简称Hop&#xff0c;全称为Hop Orchestration Platform&#xff0c;即Hop 工作编排平台&#xff0c;是一个数据编排和数据工程平台&#xff0c;旨在促进数据和元数据编排的所有方面。Hop让你专注于你想要解决的问题…

模拟SpringIOCAOP

一、IOC容器 Ioc负责创建&#xff0c;管理实例&#xff0c;向使用者提供实例&#xff0c;ioc就像一个工厂一样&#xff0c;称之为Bean工厂 1.1 Bean工厂的作用 先分析一下Bean工厂应具备的行为 1、需要一个获取实例的方法&#xff0c;根据一个参数获取对应的实例 getBean(…

基于ILI9341液晶屏+STM32U5单片的显示试验

试验要求&#xff1a; 1、通过串口&#xff0c;下发两个命令 STR和PIC&#xff1b; 2、STR模式&#xff1a; &#xff08;1&#xff09;串口输入什么&#xff0c;屏幕上显示什么 &#xff08;2&#xff09;如果屏幕满&#xff0c;自动下滚 &#xff08;3&#xff09;输入回车&a…

Elasticsearch:向量数据库基础设施类别的兴衰

过去几年&#xff0c;我一直在观察嵌入技术如何从大型科技公司的 “秘密武器” 转变为日常开发人员工具。接下来发生的事情 —— 向量数据库淘金热、RAG 炒作周期以及最终的修正 —— 教会了我们关于新技术如何在更广泛的生态系统中找到一席之地的宝贵经验。 更多有关向量搜索…

《系统爆破:MD5易破,后台登录可爆破?》

声明&#xff1a;笔记的只是方便各位师傅学习知识&#xff0c;以下代码、网站只涉及学习内容&#xff0c;其他的都与本人无关&#xff0c;切莫逾越法律红线&#xff0c;否则后果自负。 爆破Sales系统 一、爆破MD5 场景&#xff1a;已知MD5的加密字符串&#xff0c;如何得知明…

《Spring Framework实战》14:4.1.4.5.自动装配合作者

欢迎观看《Spring Framework实战》视频教程 自动装配合作者 Spring容器可以自动连接协作bean之间的关系。您可以通过检查ApplicationContext的内容&#xff0c;让Spring自动为您的bean解析协作者&#xff08;其他bean&#xff09;。自动装配具有以下优点&#xff1a; 自动装配…

GitLab CI/CD使用runner实现自动化部署前端Vue2 后端.Net 7 Zr.Admin项目

1、查看gitlab版本 建议安装的runner版本和gitlab保持一致 2、查找runner 执行 yum list gitlab-runner --showduplicates | sort -r 找到符合gitlab版本的runner&#xff0c;我这里选择 14.9.1版本 如果执行出现找不到下载源&#xff0c;添加官方仓库 执行 curl -L &quo…

冒泡排序基础与实现

目录 1. 原理图 ​编辑 2. 什么是冒泡排序 3. 工作原理 3.1 具体步骤 3.2 时间复杂度 3.3 空间复杂度 4. 代码实现 5. 总结 1. 原理图 2. 什么是冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过重复地遍历要排序的列表&am…

acwing_5722_十滴水

acwing_5722_十滴水 下面这篇大佬的题解属实是把指针用明白了&#xff0c;可以好好理解一下&#xff1a; 原题解连接&#xff1a;AcWing 5722. 一个简单模拟实现 - AcWing map/unordered_map的用法:见收藏夹 #include<iostream> #include<unordered_map> #incl…

【AI进化论】 AI微信机器人 | sealos + 智能微秘书 打造AI机器人 | 智能微秘书配置教程

一、sealos 什么是sealos &#xff1f; One cloud OS for all applications 1、创建sealos账号密码 根据链接&#xff08;帮我凑点sealos使用额度感谢&#xff09;&#xff1a;https://cloud.sealos.run/?uidXfUpoQk92c 登录后如下页面&#xff1a; 2、创建应用 点击【应…

Agentless:OpenAI 采用的非代理框架

不需要代理库来解决复杂的业务问题。Agentless 是OpenAI采用的非代理框架&#xff0c;用于在 o3 的 SWE Bench 上实现最高精度。SWE-bench 是 github的真实软件工程问题基准。Agentless 遵循简单的三阶段流程&#xff1a;本地化、修复和补丁验证&#xff1a; 1 ⃣生成存储库的…

Model-based RL自动出价算法的演进之路

▐ 导读 近年来&#xff0c;强化学习自动出价算法已成为智能投放领域的标志性技术&#xff0c;然而其所存在的在离线不一致、线上数据覆盖空间受限等关键问题尚未被完全解决。在本文中&#xff0c;我们提出一种Model-based RL&#xff08;MBRL&#xff09;自动出价算法训练新范…

【Cocos TypeScript 零基础 7.1】

目录 重写 小结一下心得页面跳转背景移动精简 player敌机精灵 重写 小结一下心得 本人重写了整个项目 有了点小心得 页面跳转 director.loadScene(s2)背景移动 canvas 是画布 为什么要向上图布局? 方便计算相对坐标,脚本还是只写一个 绑定上 BG 一样跑,不影响 export cl…

鸿蒙UI(ArkUI-方舟UI框架)

参考&#xff1a;https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/arkts-layout-development-overview-V13 ArkUI简介 ArkUI&#xff08;方舟UI框架&#xff09;为应用的UI开发提供了完整的基础设施&#xff0c;包括简洁的UI语法、丰富的UI功能&#xff…