责任链模式的应用与解析

目录

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

责任链模式

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

责任链模式结构

在这里插入图片描述

  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.rhkb.cn/news/382541.html

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

相关文章

H3CNE(OSPF动态路由)

7.1 静态路由的缺点与动态路由分类 7.1.1 静态路由的缺点 7.1.2 动态路由的分类 OSPF运行的机制&#xff1a; 1. 每个设备产生LSA后&#xff0c;都会与其他的设备同步LSA&#xff0c;通过OSPF的报文&#xff0c;去发送与接受其他的LSA&#xff0c;最终目的是每个设备都有全网所…

【BUG】已解决:ModuleNotFoundError: No module named ‘requests‘

ModuleNotFoundError: No module named ‘requests‘ 目录 ModuleNotFoundError: No module named ‘requests‘ 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&a…

Java面试题(每日更新)

每日五道&#xff01;学会就去面试&#xff01; 本文的宗旨是为读者朋友们整理一份详实而又权威的面试清单&#xff0c;下面一起进入主题吧。 目录 1.概述 2.Java 基础 2.1 JDK 和 JRE 有什么区别&#xff1f; 2.2 和 equals 的区别是什么&#xff1f; 2.3 两个对象的…

【LeetCode】86.分割链表

1. 题目 2. 分析 这题没有太大难度&#xff0c;主要是熟悉代码。 3. 代码 # Definition for singly-linked list. # class ListNode: # def __init__(self, val0, nextNone): # self.val val # self.next next class Solution:def partition(self, he…

SQL中的LEFT JOIN、RIGHT JOIN和INNER JOIN

在SQL中&#xff0c;JOIN操作是连接两个或多个数据库表&#xff0c;并根据两个表之间的共同列&#xff08;通常是主键和外键&#xff09;返回数据的重要方法。其中&#xff0c;LEFT JOIN&#xff08;左连接&#xff09;、RIGHT JOIN&#xff08;右连接&#xff09;和INNER JOIN…

windows服务器启动apache失败,提示请通过cmd命令行启动:net start apache

Windows Server 2012 R2服务器突然停止运行apche&#xff0c;启动apache失败&#xff0c;提示请通过cmd命令行启动:net start apache 1.报错截图&#xff1a; 进入服务里输入命令启动也不行&#xff0c;提示由于登录失败而无法启动服务。 2.问题原因&#xff1a; 服务器www用…

Yolo-World网络模型结构及原理分析(三)——RepVL-PAN

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言1. 网络结构2. 特征融合3. 文本引导&#xff08;Text-guided&#xff09;4. 图像池化注意力&#xff08;Image-Pooling Attention&#xff09;5. 区域文本匹配&…

Invalid bound statement (not found)

Invalid bound statement (not found) 首先申明的是这个错误一般是使用mybatis方法没有找到或者参数不匹配等原因造成的&#xff01; 原本项目是使用eclipse运行&#xff0c;导入到idea之后&#xff0c;项目启动就报错 …Invalid bound statement (not found)… 解决办法&#…

下载最新版Anaconda、安装、更换源、配置虚拟环境并在vscode中使用

文章目录 进入官网进入下载页安装更换源配置虚拟环境env安装包requests在vscode中使用虚拟环境 进入官网 https://repo.anaconda.com/ 或进入清华大学下载 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 进入下载页 安装 更换源 查看已经存在的镜像源 bash cond…

【机器学习】Jupyter Notebook如何使用之基本步骤和进阶操作

引言 Jupyter Notebook 是一个交互式计算环境&#xff0c;它允许创建包含代码、文本和可视化内容的文档 文章目录 引言一、基本步骤1.1 启动 Jupyter Notebook1.2 使用 Jupyter Notebook 仪表板1.3 在笔记本中工作1.4 常用快捷键1.5 导出和分享笔记本 二、进阶用法2.1 组织笔…

天工Godwork AT 5.2.6 GodWork2D 2.1.5 GodWork EOS 2.1实景三维建模软件

天工Godwork AT 5.2.6/GodWork2D 2.1.5/GodWork EOS 2.1实景三维建模软件 获取安装包联系邮箱:2895356150qq.com 本介绍用于学习使用&#xff0c;如有侵权请您联系删除&#xff01; 1.自主研发的平差技术&#xff0c;平差模块不依赖PATB、Bingo等国外技术 2.采用特征匹配&…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第三篇 嵌入式Linux驱动开发篇-第四十七章 字符设备和杂项设备总结回顾

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

【es】elasticsearch 自定义排序-按关键字位置排序

一 背景 要求es查询的结果按关键字位置排序&#xff0c;位置越靠前优先级越高。 es版本7.14.0&#xff0c;项目是thrift&#xff0c;也可以平替springboot&#xff0c;使用easyes连接es。 二 easyes使用 配easyes按官方文档就差不多了 排序 | Easy-Es 主要的一个问题是easy…

HTTPServer改进思路2(mudou库核心思想融入)

mudou网络库思想理解 Reactor与多线程 服务器构建过程中&#xff0c;不仅仅使用一个Reactor&#xff0c;而是使用多个Reactor&#xff0c;每个Reactor执行自己专属的任务&#xff0c;从而提高响应效率。 首先Reactor是一种事件驱动处理模式&#xff0c;其主要通过IO多路复用…

ST Stellar-E SR5E1 22KW OBC combo 3KW DC-DC汽车充电器解决方案

对于全球的环境保护意识抬头&#xff0c;全球的汽车产业慢慢步入电动化的时代&#xff0c;以减少碳排放。整车系统主要是由电池、电驱、电控的三电所构成&#xff0c;其中电池系统是整车的动力来源&#xff0c;而对电池充电的OBC系统更甚重要。一具高度安全性且高效的OBC系统&a…

7.23 字符串简单中等 520 125 14 34

520 Detect Capital 思路&#xff1a; 题目&#xff1a;判定word &#xff1a;if the usage of capitals in it is right.遍历所有的string&#xff1a; 两种情况&#xff1a; 首字母capitals–>判定第二个字母是否大写–>所有字母大写 otherwise 除第一个以外全部小写&a…

使用xxl-job执行定时任务

文章目录 使用xxl-job执行定时任务xxl-job原理我们自己的项目里面需要怎么写定时任务呢&#xff1f;如果想要使用xxl-job我们需要在服务器上部署两个项目 使用xxl-job执行定时任务 xxl-job原理 首先xxl-job的全拼是“XiaoXiaoLiang Job”或者“Xu Xue Li”作者的名字&#xf…

华清数据结构day4 24-7-19

链表的相关操作 linklist.h #ifndef LINKLIST_H #define LINKLIST_H #include <myhead.h> typedef int datatype; typedef struct Node {union{int len;datatype data;};struct Node *next; } Node, *NodePtr;NodePtr list_create(); NodePtr apply_node(datatype e); …

从零开始学Java(超详细韩顺平老师笔记梳理)06——面向对象编程基础(上):类与对象、成员方法、传参机制、对象克隆、递归(斐波那契、迷宫、汉诺塔、八皇后)

文章目录 前言一、类与对象1. 类与对象的概述2. 快速入门&#xff08;用面向对象的方式解决问题&#xff09;3. 对象在内存中的存在形式&#xff08;重要&#xff09;4. 属性5. 类与对象的内存分配机制 二、成员方法1. 基本介绍2. 快速入门3. 方法调用机制原理&#xff08;重点…

【HarmonyOS学习】用户文件访问

概述 文件所有者为登录到该终端设备的用户&#xff0c;包括用户私有的图片、视频、音频、文档等。 应用对用户文件的创建、访问、删除等行为&#xff0c;需要提前获取用户授权&#xff0c;或由用户操作完成。 用户文件访问框架 是一套提供给开发者访问和管理用户文件的基础框…