责任链模式的应用与解析

目录

  • 责任链模式
    • 责任链模式结构
    • 责任链模式适用场景
    • 责任链模式优缺点
    • 练手题目
      • 题目描述
      • 输入描述
      • 输出描述
      • 题解

责任链模式

责任链模式,亦称职责链模式、命令链,是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。

责任链模式结构

在这里插入图片描述

  1. 处理者(Handler)声明了所有具体处理者的通用接口。该接口通常仅包含单个方法用于请求处理,但有时其还会包含一个设置链上下个处理者的方法。

  2. 基础处理者(Base Handler)是一个可选的类,你可以将所有处理者共用的样本代码放置在其中。通常情况下,该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。该类还可以实现默认的处理行为:确定下个处理者存在后再将请求传递给它。

  3. 具体处理者(Concrete Handlers)包含处理请求的实际代码。每个处理者接收到请求后,都必须决定是否进行处理,以及是否沿着链传递请求。处理者通常是独立且不可变的,需要通过构造函数一次性地获得所有必要地数据。

  4. 客户端(Client)可根据程序逻辑一次性或者动态地生成链。值得注意的是,请求可发送给链上的任意一个处理者,而非必须是第一个处理者。

责任链模式通用代码:

//抽象处理者
public abstract class Handler{//下一个处理者private Handler nextHandler;// 对请求做出处理public final Response handleMessage(Request request){Response response = null ;//判断处理级别if(this.getHandlerLever().equals(request.getHandlerLever())){response = this.echo(request);}else{if(this.nextHandler != null){response = this.nextHandler.handleMessage(request);}else{...}return response;}public void setNext(Handler _handler){this.nextHandler = _handler;}//处理级别protected abstract Level getHandlerLevel();//处理任务protected abstract Response echo(Request request);}//具体处理者
public class ConcreteHandler1 extends Handler {//级别protected abstract Level getHandlerLevel(){...
}//处理任务protected abstract Response echo(Request request){...
}
}public class Level{}public class Request{public Level getRequestLevel(){...}
}public class Response{...
}

责任链模式适用场景

  1. 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。

  2. 当必须按顺序执行多个处理者时, 可以使用该模式。

  3. 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。

在这里插入图片描述

**识别方法:**该模式可通过一组对象的行为方法间接调用其他对象的相同方法来识别, 而且所有对象都会遵循相同的接口。

责任链模式优缺点

责任链模式优点:

  • 你可以控制请求处理的顺序。

  • 单一职责原则。 你可对发起操作和执行操作的类进行解耦。

  • 开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。

责任链模式缺点:

  • 部分请求可能未被处理。

练手题目

题目描述

小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。

审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。

输入描述

第一行是一个整数N(1 <= N <= 100), 表示请求申请的数量。

接下来的N行,每行包括一个请求申请的信息,格式为"姓名 请假天数"

输出描述

对于每个请假请求,输出一行,表示该请求是否被批准。如果被批准/否决,输出被哪一个职级的人批准/否决。

在这里插入图片描述

题解

初始解法:

import java.util.Scanner;/*** 抽象处理器类,定义了责任链的基本结构*/
abstract class Handler {public final static int SUPERVISOR_LEVEL_REQUEST = 1;public final static int MANAGER_LEVEL_REQUEST = 2;public final static int DIRECTOR_LEVEL_REQUEST = 3;private Handler nextHandler;private int level = 0;public Handler(int level) {this.level = level;}/*** 处理请求的方法* @param request 需要处理的请求* @return 处理结果*/public final Response handleRequest(Request request) {if (this.level == request.getRequestLevel()) {return this.response(request);} else {if (this.nextHandler != null) {return this.nextHandler.handleRequest(request);} else {return new Response("Request denied");}}}/*** 设置下一个处理器* @param nextHandler 下一个处理器*/public void setNext(Handler nextHandler) {this.nextHandler = nextHandler;}/*** 具体的响应方法,由子类实现* @param request 需要处理的请求* @return 处理结果*/protected abstract Response response(Request request);
}/*** 主管处理*/
class SupervisorHandler extends Handler {public SupervisorHandler() {super(Handler.SUPERVISOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Supervisor.");return new Response("Approved by Supervisor");}
}/*** 经理处理*/
class ManagerHandler extends Handler {public ManagerHandler() {super(Handler.MANAGER_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Manager.");return new Response("Approved by Manager");}
}/*** 董事处理*/
class DirectorHandler extends Handler {public DirectorHandler() {super(Handler.DIRECTOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Director.");return new Response("Approved by Director");}
}/*** 请求类,包含请求的详细信息*/
class Request {private String name;private int level = 0;private int nums;public Request(String name, int nums) {this.name = name;this.nums = nums;if (nums > 0 && nums <= 3) {level = Handler.SUPERVISOR_LEVEL_REQUEST;} else if (nums > 3 && nums <= 5) {level = Handler.MANAGER_LEVEL_REQUEST;} else if (nums > 5 && nums <= 10) {level = Handler.DIRECTOR_LEVEL_REQUEST;} else {level = -1;}}public int getRequestLevel() { return this.level; }public String getName() { return this.name; }public int getNums() { return this.nums; }
}/*** 响应类,包含处理结果*/
class Response {private String message;public Response(String message) {this.message = message;}public String getMessage() {return this.message;}
}public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 创建处理器链SupervisorHandler supervisorHandler = new SupervisorHandler();ManagerHandler managerHandler = new ManagerHandler();DirectorHandler directorHandler = new DirectorHandler();supervisorHandler.setNext(managerHandler);managerHandler.setNext(directorHandler);int n = scanner.nextInt();scanner.nextLine(); while (n-- > 0) {String[] s = scanner.nextLine().split(" ");Request request = new Request(s[0], Integer.parseInt(s[1]));Response response = supervisorHandler.handleRequest(request);if (request.getRequestLevel() == -1) {System.out.println(request.getName() + " Denied by Director.");}}scanner.close();}
}

优化后:

import java.util.Scanner;// 抽象处理器类,定义了责任链的基本结构
abstract class Handler {public final static int SUPERVISOR_LEVEL_REQUEST = 1;public final static int MANAGER_LEVEL_REQUEST = 2;public final static int DIRECTOR_LEVEL_REQUEST = 3;private Handler nextHandler;private int level = 0;// 构造函数,设置处理器的级别public Handler(int _level) {this.level = _level;}// 处理请求的方法public final Response handleMessage(Request request) {if (this.level == request.getRequestLevel()) {return this.response(request);} else {if (this.nextHandler != null) {return this.nextHandler.handleMessage(request);} else {return new Response("Request denied");}}}// 设置下一个处理器public void setNext(Handler _handler) {this.nextHandler = _handler;}protected abstract Response response(Request request);
}// 主管处理
class SupervisorHandler extends Handler {public SupervisorHandler() {super(Handler.SUPERVISOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Supervisor.");return new Response("Approved by Supervisor");}
}// 经理处理
class ManagerHandler extends Handler {public ManagerHandler() {super(Handler.MANAGER_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Manager.");return new Response("Approved by Manager");}
}// 董事处理
class DirectorHandler extends Handler {public DirectorHandler() {super(Handler.DIRECTOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Director.");return new Response("Approved by Director");}
}// 请求级别的枚举,定义了不同级别的请假天数范围
enum RequestLevel {SUPERVISOR(1, 3),MANAGER(4, 5),DIRECTOR(6, 10);private final int minDays;private final int maxDays;RequestLevel(int minDays, int maxDays) {this.minDays = minDays;this.maxDays = maxDays;}// 根据天数确定请求级别public static RequestLevel fromDays(int days) {for (RequestLevel level : values()) {if (days >= level.minDays && days <= level.maxDays) {return level;}}return null;}public int getValue() {return ordinal() + 1;}
}// 请求类,包含请求的详细信息
class Request {private String name;private int level;private int nums;public Request(String name, int nums) {this.name = name;this.nums = nums;RequestLevel requestLevel = RequestLevel.fromDays(nums);this.level = (requestLevel != null) ? requestLevel.getValue() : -1;}public int getRequestLevel() {return this.level;}public String getName() {return this.name;}public int getNums() {return this.nums;}
}// 响应类,包含处理结果
class Response {private String message;public Response(String message) {this.message = message;}public String getMessage() {return this.message;}
}// 主类
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 创建处理器链SupervisorHandler supervisorHandler = new SupervisorHandler();ManagerHandler managerHandler = new ManagerHandler();DirectorHandler directorHandler = new DirectorHandler();// 设置处理器链的顺序supervisorHandler.setNext(managerHandler);managerHandler.setNext(directorHandler);int n = scanner.nextInt();scanner.nextLine(); // 处理每个请求while (n-- > 0) {String[] s = scanner.nextLine().split(" ");Request request = new Request(s[0], Integer.parseInt(s[1]));Response response = supervisorHandler.handleMessage(request);if (request.getRequestLevel() == -1) {System.out.println(request.getName() + " Denied by Director.");}}scanner.close();}
}

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

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

相关文章

26.8 Django多表操作

1. 表关系 表关系在数据库中指的是表与表之间的连接和依赖关系. 这种关系定义了数据如何在不同的表之间进行交互和关联, 是实现数据一致性和完整性的重要手段.1.1 关系分类 多表关系在数据库中通常分为以下几种类型: * 1. 一对一(One-to-One)关系: 在数据库中, 这种关系通常通…

模拟建造游戏:城市:天际线2(都市天际线2)中文免安装,解压即撸

《城市&#xff1a;天际线2》&#xff08;Cities: Skylines II&#xff09;是一款模拟经营游戏&#xff0c;由Colossal Order开发&#xff0c;Paradox Interactive发行。 下载地址&#xff1a;https://pan.quark.cn/s/84e69332ec3e 更多游戏&#xff1a;https://kdocs.cn/l/cuH…

spring 中的属性解析器 PropertyResolver

我们知道&#xff0c;在 spring 中可以使用占位符&#xff0c;格式如 "${}"&#xff0c;大括号中间放置待替换的占位符&#xff0c;待使用值时根据配置的属性解析器进行解析。但具体是如何操作的&#xff0c;且看本文来进行分析。 PropertyResolver 这是一个针对任…

基于Neo4j将知识图谱用于检索增强生成:Knowledge Graphs for RAG

Knowledge Graphs for RAG 本文是学习https://www.deeplearning.ai/short-courses/knowledge-graphs-rag/这门课的学习笔记。 What you’ll learn in this course Knowledge graphs are used in development to structure complex data relationships, drive intelligent sea…

GDAL访问HDFS集群中的数据

1.集群搭建 参考文章&#xff1a;hadoop2.10.0完全分布式集群搭建 HA(QJM)高可用集群搭建_hadoop 2.10 ha-CSDN博客 创建文件夹 hdfs dfs -mkdir -p hdfs://192.168.80.132:9000/test 开放权限 hdfs dfs -chmod -R 777 /test 上传文件 hadoop fs -put /home/wh/data/res…

卡夫卡(Kafka)框架详解:从背景到应用实践

卡夫卡&#xff08;Kafka&#xff09;框架详解&#xff1a;从背景到应用实践 引言 在大数据和分布式系统日益普及的今天&#xff0c;数据处理和消息传递成为了支撑复杂业务系统的关键基础设施。Apache Kafka&#xff0c;作为一个高性能的分布式消息队列系统&#xff0c;因其高…

CSS技巧专栏:一日一例 11 -纯CSS实现多彩渐变按钮系列特效

CSS技巧专栏&#xff1a;一日一例 11 -纯CSS实现多彩渐变按钮系列特效 本篇&#xff0c;推荐给你几个按钮&#xff0c;先看一下图片 本例图片 案例分析 这是一个系列的按钮&#xff0c;它们具有共同的特点&#xff1a; 底层按钮层&#xff0c;具有一个彩色的渐变边框&#…

第十四章 数据库

第十四章 数据库 14.1 引言 数据存储在传统上是使用单独的没有关联的文件&#xff0c;称为平面文件 14.1.1 定义 定义&#xff1a;数据库是一个组织内被应用程序使用的逻辑相一致的相关数据的集合 14.1.2 数据库的优点 数据库的优点&#xff1a; 冗余少避免数据的不一致…

docker产生日志过大优化

1、Docker容器启动后日志存放位置 #cat /var/lib/docker/containers/容器ID/容器ID-json.log #echo >/var/lib/docker/containers/容器ID/容器ID-json.log临时清除日志 注&#xff1a;echo一个空进去&#xff0c;不需要重启容器&#xff0c;但如果你直接删除这个日志&…

【JavaEE】Bean的作用域和生命周期

一.Bean的作用域. 1.1 Bean的相关概念. 通过Spring IoC和DI的学习(不清楚的可以看的前面写过的总结,可以快速入门, http://t.csdnimg.cn/K8Xr0),我们知道了Spring是如何帮助我们管理对象的 通过 Controller , Service , Repository , Component , Configuration , Bean 来声明…

无人机之航拍高级操作与技巧

一、直线飞行与矩形飞行练习&#xff1a;通过直线和矩形路径的练习&#xff0c;提升飞行路径控制能力。 二、航点命令和事件编程&#xff1a;学习如何设置航点命令和事件&#xff0c;使无人机能够自动执行复杂任务。 三、故障诊断与处理&#xff1a;掌握基本的故障诊断方法和…

如何使用 API list 极狐GitLab 群组中的镜像仓库?

GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab &#xff1a;https://gitlab.cn/install?channelcontent&utm_sourcecsdn 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署…

深入指南:VitePress 如何自定义样式

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

PHP安全编程宝典:30000字精细解析

文章目录 基础语法单双引号的区别前后端分离数据类型PHP常量函数var_dump函数count函数print_r函数**readfile&#xff08;&#xff09;函数****file_get_contents()函数****file_put_contents()函数**header函数fopen函数fread 函数rename函数copy&#xff08;&#xff09;函数…

【时时三省】(C语言基础)结构体

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ——csdn时时三省 结构体 结构体使得C语言有能力描述复杂类型。 结构体可以让c语言创造新的类型出来 示例: struct Stu &#xff5b; char name&#xff3b;20&#xff3d; &#xff08;名字的话是一个字…

数学建模--简单优化模型之存储模型

目录 1.问题概述 1.1问题介绍 1.2优化目标 2.问题的分析与思考 2.1已知条件的说明 2.2正确的理解准备费 2.3三个举例 3.模型的假设 4.模型的建立与求解 4.1模型的建立 4.2模型的求解 5.灵敏度分析 6.模型推广 1.问题概述 1.1问题介绍 上面这个已经介绍了&#xff…

web小项目-曼波生日录(Servlet+JSP+MySQL)

效果演示&#xff1a; 当记录条数过多时会自动出现滚轮&#xff0c;数据不会超出紫框 数据库实时记录&#xff1a; 项目源代码以及所用到的资源&#xff1a; 链接: https://pan.baidu.com/s/1w0czmH9xBfetk7CZ7RNbtQ?pwd6666 提取码: 6666 复制这段内容后打开百度网盘手机App…

PaddleOCR-PP-OCRv4推理详解及部署实现(下)

目录 前言1. 检测模型1.1 预处理1.2 后处理1.3 推理 2. 方向分类器模型2.1 预处理2.2 后处理2.3 推理 3. 识别模型3.1 预处理3.2 后处理3.3 推理 4. PP-OCRv4部署4.1 源码下载4.2 环境配置4.2.1 配置CMakeLists.txt4.2.2 配置Makefile 4.3 ONNX导出4.4 engine生成4.4.1 检测模型…

linux进程——解析命令行参数——环境变量详解

前言&#xff1a;本节内容还是linux进程&#xff0c; 主要讲解里面的环境变量——我们首先要知道的就是环境变量其实就是操作系统维护的一组kv值&#xff0c; 环境变量是系统提供的一组 变量名变量值 形式的变量。不同的环境变量之间具有不同的用途&#xff0c; 并且具有全局属…

(雷达数据处理中的)跟踪算法(4) --- 基于数据集的目标跟踪实践

说明 本文作为跟踪系列的第4篇博文&#xff0c;在前面几篇博文[1][2][3]的基础上对所采集的实际数据(来自国防科技大学电子科学学院所主导发布的数据集[4])进行跟踪实践。读者在阅读本文前&#xff0c;建议先阅读本系列的前3篇博文。 Blog 20240724 博文第一次撰写 目录 说明…