20 设计模式之职责链模式(问题处理案例)
一、什么是职责链模式
职责链模式是一种行为型设计模式,它允许将请求沿着处理者的链进行传递,直到有一个处理者能够处理它为止。换句话说,它将请求的发送者和接收者解耦,使得多个对象都有机会处理这个请求,从而避免了将请求直接发送给具体的处理者。
在职责链模式中,多个处理者对象形成一个链,客户端将请求传递给链中的第一个处理者,由第一个处理者决定是自己处理请求,还是将请求传递给下一个处理者,直到请求被处理或者链末尾没有处理者为止。
二、职责链模式的结构
- Handler(处理者):定义处理请求的接口,并且可以访问下一个处理者。
- ConcreteHandler(具体处理者):实现了处理请求的具体逻辑,如果能够处理该请求,则处理它,如果不能处理,则将请求传递给链中的下一个处理者。
- Client(客户端):发起请求并传递给链中的第一个处理者。
三、职责链模式的优点
- 降低耦合性:请求发送者和请求接收者解耦,发送者无需知道具体处理者。
- 灵活性:可以灵活地组织处理者链,可以动态地改变链的结构。
- 简化代码:职责链模式可以避免多重条件语句,使代码更简洁。
四、职责链模式的缺点
- 链过长:如果链太长,可能会导致性能问题。
- 处理不当:如果没有合适的处理者,可能会造成请求得不到处理。
五、案例讲解:客服支持系统
假设我们有一个客服支持系统,客户提交的问题根据其优先级需要经过不同层级的客服人员处理。优先级较低的问题由初级客服处理,优先级较高的问题由技术支持人员处理,如果问题依然没有解决,那么会交给经理来处理。
我们可以使用职责链模式来处理这个场景。以下是完整的代码实现。
六、代码实现
1.问题设计(SupportTicket)
public class SupportTicket {private String description; // 问题描述private int priority; // 问题优先级,数值越大表示优先级越高public SupportTicket(String description, int priority) {this.description = description;this.priority = priority;}public String getDescription() {return description;}public int getPriority() {return priority;}
}
SupportTicket
类表示客户提交的问题,包含问题的描述和优先级。
2.抽象支持处理者(SupportHandler)
public abstract class SupportHandler {private SupportHandler nextHandler; // 下一个处理者// 设置下一个处理者public void setNextHandler(SupportHandler nextHandler){this.nextHandler = nextHandler;}// 获取下一个处理者public SupportHandler getNextHandler(){return nextHandler;}// 处理请求的方法public abstract void handleTicket(SupportTicket ticket);
}
SupportHandler
是职责链模式中的抽象处理者,它定义了处理请求的方法 handleTicket
,并且维护了一个指向下一个处理者的引用(nextHandler
)。
3.初级支持处理者(JuniorSupport)
public class JuniorSupport extends SupportHandler{@Overridepublic void handleTicket(SupportTicket ticket) {if(ticket.getPriority() <= 2){System.out.println("初级客服处理问题:"+ticket.getDescription());} else if (getNextHandler() != null) {getNextHandler().handleTicket(ticket); // 传递给下一个处理者} else {System.out.println("问题过大,需要汇报给总部处理!!!");}}
}
JuniorSupport
是一个具体处理者类,当问题的优先级小于等于 2 时,它会处理该问题。如果问题优先级较高,它会将请求传递给下一个处理者。
4.技术支持处理者(TechSupport)
public class TechSupport extends SupportHandler{@Overridepublic void handleTicket(SupportTicket ticket) {if(ticket.getPriority() <= 4){System.out.println("技术员处理问题:"+ticket.getDescription());} else if (getNextHandler() != null) {getNextHandler().handleTicket(ticket); // 传递给下一个处理者} else {System.out.println("问题过大,需要汇报给总部处理!!!");}}
}
TechSupport
处理优先级小于等于 4 的问题,其他问题会传递给下一个处理者。
5.经理支持处理者(ManagerSupport)
public class ManagerSupport extends SupportHandler{@Overridepublic void handleTicket(SupportTicket ticket) {if(ticket.getPriority() <= 10){System.out.println("经理处理问题:"+ticket.getDescription());} else if (getNextHandler() != null) {getNextHandler().handleTicket(ticket);} else {System.out.println("问题过大,需要汇报给总部处理!!!");}}
}
ManagerSupport
处理优先级小于等于 10 的问题,其他问题会传递给下一个处理者,直到链的末尾。
6.测试类(TestChain)
public class TestChain {public static void main(String[] args) {// 问题声明SupportTicket ticket1 = new SupportTicket("线路混乱", 1);SupportTicket ticket2 = new SupportTicket("服务器异常", 113);// 处理者声明SupportHandler handler1 = new JuniorSupport();SupportHandler handler2 = new TechSupport();SupportHandler handler3 = new ManagerSupport();// 处理者链的组装handler1.setNextHandler(handler2);handler2.setNextHandler(handler3);// 问题处理的传递handler1.handleTicket(ticket1);handler1.handleTicket(ticket2);}
}
在 TestChain
中,我们创建了三个处理者(JuniorSupport
、TechSupport
、ManagerSupport
),并将它们串联成一个处理链。当请求传递给第一个处理者时,若它不能处理请求,就将请求交给下一个处理者,直到找到合适的处理者或者到达链的末尾。
7. 总结
职责链模式通过将请求沿着处理者链进行传递,使得每个处理者只关心自己能处理的请求,从而减少了发送者与接收者之间的耦合。职责链模式有助于系统的灵活扩展,因为我们可以在运行时动态地调整处理链结构。通过这种模式,能够实现请求的逐层处理,直到有一个处理者能够处理该请求为止。
相关文章:
20 设计模式之职责链模式(问题处理案例)
一、什么是职责链模式 职责链模式是一种行为型设计模式,它允许将请求沿着处理者的链进行传递,直到有一个处理者能够处理它为止。换句话说,它将请求的发送者和接收者解耦,使得多个对象都有机会处理这个请求,从而避免了将…...
SpringBoot3集成MybatisPlus3和knife4j(swagger3兼容增强版)
针对Swagger2规范和OpenAPI3规范的说明: 在Spring Boot框架中,Knife4j对于服务端将Spring的开放接口解析成Swagger2或者OpenAPI3规范的框架,也是依赖的第三方框架组件。说明如下: Swagger2规范:依赖Springfox项目,该项目目前几乎处于停更状态,但很多老项目依然使用的是该…...
【MIT-OS6.S081作业1.3】Lab1-utilities primes
本文记录MIT-OS6.S081 Lab1 utilities 的primes函数的实现过程 文章目录 1. 作业要求primes (moderate)/(hard) 2. 实现过程2.1 代码实现 1. 作业要求 primes (moderate)/(hard) Write a concurrent version of prime sieve using pipes. This idea is due to Doug McIlroy, in…...
游戏引擎学习第35天
开场介绍 今天的任务是继续改进一个虚拟的瓦片地图系统,使其适合处理更大的世界。我们希望这个系统能管理大范围的游戏世界,其中包含按需存储的小区域。昨天,我们介绍了“内存区域”的概念,用于管理持久性存储。我们计划今天继续…...
learn-(Uni-app)输入框u-search父子组件与input输入框(防抖与搜索触发)
1.父子组件u-search (1)父组件 <!-- 父组件 --> <template> <div><searchBar change"change" search"search"></searchBar> </div> </template> <script> // 子组件搜索 import…...
设置IMX6ULL开发板的网卡IP的两种方法(临时生效和永久有效两种方法)
设置开发板网卡的IP,有两种方法。 方法一:临时生效 第一种方式是临时设置,只有本次有效,重启后又要重新设,命令为: ifconfig eth0 192.168.5.9设置成功后可以使用ifconfig命令来查看已设置的 IP 地址。 …...
流量转发利器之Burpsuite概述(1)
目录 一、Burpsuite Burp Suite Spider 的主要特点: 在 Burp Suite 中使用 Spider: Spider 的用例: 限制: 声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章 声明:本文主要用作技…...
Transformer入门(6)Transformer编码器的前馈网络、加法和归一化模块
文章目录 7.前馈网络8.加法和归一化组件9.组合所有编码器组件构成完整编码器 7.前馈网络 编码器块中的前馈网络子层如下图所示: 图1.32 – 编码器块 前馈网络由两个带有ReLU激活函数的全连接层组成。全连接层(Fully Connected Layer)有时也…...
element-plus中的resetFields()方法
resetFields()确实是Element Plus中的方法,该方法主要用于重置表单,将其值重置为初始值,并移除校验结果。以下是对该方法的详细解释: 一、resetFields方法的作用 在Vue3结合Element Plus开发时࿰…...
【过滤器】.NET开源 ORM 框架 SqlSugar 系列
目录 0、 过滤器介绍 1、表过滤器 (推荐) 1.1 手动添加过滤器 1.2 禁用、清空、备份和还原 1.3 联表查询设置 1.4 动态添加 2、修改和删除用过滤器 2.1 局部设置 2.2 全局设置 (5.1.4.62) 3、子查询用过滤器 4、联表过滤…...
Jmeter Address already in use: connect 解决
做压测接口时,并发一段时间后,会报java.net.BindException: Address already in use: connect 原因: windows提供给TCP/IP链接的端口为 1024-5000,并且要四分钟来循环回收它们,就导致在短时间内跑大量的请求时将端口占…...
C#常见错误—空对象错误
System.NullReferenceException:未将对象引用设置到对象的实例 在C#编程中,System.NullReferenceException是一个常见的运行时异常,其错误信息“未将对象引用设置到对象的实例”意味着代码试图访问一个未被初始化或已被设置为null的对象的成…...
Leetcode数学部分笔记
Leetcode数学部分笔记 1. 回文数2. 加一3. 阶乘后的零4. x 的平方根5. Pow(x, n) 1. 回文数 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数 是指正序(从左向右)和倒序&…...
微信小程序web-view 嵌套h5界面 实现文件预览效果
实现方法:(这里我是在小程序里面单独加了一个页面用来下载预览文件) 安装 使用方法请参考文档 npm 安装 npm install weixin-js-sdk import wx from weixin-js-sdk预览 h5界面代码 <u-button click"onclick" type"primary" :loading"…...
【汽车】-- 燃油发动机3缸和4缸
3缸和4缸燃油发动机是小轿车常见的发动机配置。以下从结构特点、性能、经济性等方面对两者进行对比,并分析优缺点及使用注意事项: 1. 结构与运行原理 3缸发动机 特点:少一个气缸,内部零部件更少,整体结构更紧凑。优点…...
轻量级的 HTML 模板引擎
Mustache 简介:Mustache 是一个非常简单的逻辑少的模板引擎,支持 HTML 文件中的占位符替换。它不会执行复杂的逻辑,只支持简单的变量替换。 安装: npm install mustache示例: const Mustache require(mustache);c…...
Mysql | 尚硅谷 | 第02章_MySQL环境搭建
Mysql笔记:第02章_MySQL环境搭建 说明:本内容整理自尚硅谷B站MySQL视频>>尚硅谷B站MySQL视频 文章目录 Mysql笔记:第02章_MySQL环境搭建第02章_MySQL环境搭建 1. MySQL的卸载步骤1:停止MySQL服务步骤2:[软件](h…...
Maven学习(传统Jar包管理、Maven依赖管理(导入坐标)、快速下载指定jar包)
目录 一、传统Jar包管理。 (1)基本介绍。 (2)传统的Jar包导入方法。 1、手动寻找Jar包。并放置到指定目录下。 2、使用IDEA的库管理功能。 3、配置环境变量。 (3)传统的Jar包管理缺点。 二、Maven。 &#…...
CTF: 在本地虚拟机内部署CTF题目docker
step 1 安装基本依赖 sudo apt-get update sudo apt-get install -y \ca-certificates \curl \gnupg \lsb-releasestep 2 安装docker sudo apt-get remove docker docker.io containerd runc sudo apt-get update sudo apt-get install \apt-transport-https \ca-certificate…...
视频推拉流EasyDSS无人机直播技术巡查焚烧、烟火情况
焚烧作为一种常见的废弃物处理方式,往往会对环境造成严重污染。因此,减少焚烧、推广绿色能源和循环经济成为重要措施。通过加强森林防灭火队伍能力建设与长效机制建立,各地努力减少因焚烧引发的森林火灾,保护生态环境。 巡察烟火…...
SpringBoot【十一】mybatis-plus实现多数据源配置,开箱即用!
一、前言🔥 环境说明:Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 正常情况下我们在开发系统的时候都是使用一个数据源,但是由于有些项目同步数据的时候不想造成数据库io消耗压力过大,便会一个项目对应多个数据源…...
【嵌入式linux基础】关于linux文件多次的open
在 Linux 中,设备文件可以被多次打开(open()),但这取决于具体的设备类型和其驱动程序的实现。以下是关于设备文件多次打开的一些关键点: 普通字符设备: 对于大多数字符设备,如串口、TTY 设备等&…...
TPAMI 2023:When Object Detection Meets Knowledge Distillation: A Survey
摘要 目标检测(Object Detection,OD)是计算机视觉中的一项关键任务,多年来涌现出了众多算法和模型。尽管当前 OD 模型的性能有所提升,但它们也变得更加复杂,由于参数规模庞大,在工业应用中并不…...
2024前端面试题(持续更新)
目录 一、js的数据类型有哪些? 二、什么是symbol? 三、什么是浅拷贝什么是深拷贝? 四、vue2的生命周期? 五、vue2中父子组件的生命周期调用顺序 六、vue3的生命周期 七、vue3对比vue2的变化 八、组合式API中的ref和reactiv…...
apache转nginx访问变成下载解决方法
在配置文件 nginx.conf中存在 第一行: include mine.types 对应了文件的mime类型。 第二行: 默认的是octet-stream, 意思是如果一个文件的mime类型不存在就会使用默认的类型。 通常是这个导致了文件的下载。 第一种方案:(推荐&a…...
【iOS】OC高级编程 iOS多线程与内存管理阅读笔记——自动引用计数(三)
目录 ARC规则 概要 所有权修饰符 __strong修饰符 __weak修饰符 __unsafe_unretained修饰符 __autoreleasing修饰符 ARC规则 概要 “引用计数式内存管理”的本质部分在ARC中并没有改变,ARC只是自动地帮助我们处理“引用计数”的相关部分。 在编译单位上可以…...
Oracle数据库使用dblink是时出现 ORA-12170:TNS:连接超时
原因: 我遇到这种情况是因为dblink那端的数据库被我重新导了一下dmp,然后本地这边查询就报错了。 解决办法: 把已有的dblink删掉或者说是换个名字,然后按照原来的再新建一个同名的dblink就解决了。...
OpenHarmony系统中实现Android虚拟化、模拟器相关的功能,包括桌面显示,详细解决方案
在 OpenHarmony 系统中实现 Android 虚拟化 和 模拟器功能(面显包括桌示)是一个复杂的任务,涉及多个关键技术栈的集成和深度定制。我们可以通过多种方式来实现 Android 系统的虚拟化和模拟器功能,类似于在普通操作系统中运行虚拟机…...
决策曲线分析(DCA)中平均净阈值用于评价模型算法(R自定义函数)
决策曲线分析(DCA)中平均净阈值用于评价模型算法 DCA分析虽然不强调用来评价模型算法或者变量组合的优劣,但是实际应用过程中感觉DCA曲线的走势和模型的效能具有良好的一致性,其实这种一致性也可以找到内在的联系,比如…...
《经验分享 · 软考系统分析师》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...
陈村网站建设/seo新方法
基于云服务创建离线数据统计分析服务 离线数据统计分析 使用数据工厂、数据计算服务产品,可对多源数据(DB,FILE)整合分析,制定周期性的调度任务,提供任务监控及预警、数据统计分析等功能,可对接BI报表产品…...
wordpress首页优化/seo在线优化
不久前刚买了新的笔记本,要在Win7下重新安装JDK(java开发工具)以及IDE(集成开发环境),于是顺便把安装过程记录下来。 第一步:下载JDK JDK下载网址:http://www.oracle.com/technetwork/java/java…...
中企动力科技股份有限公司销售/互联网优化
1. Class类的使用 1.1 class的获取有三种方式 F fnew F();//方法一 任何一个类都有一个隐含的静态成员变量classClass c1F.class;//方法二 已经知道该类的对象通过getClass方法Class c2f.getClass();System.out.println(c1c2); //true//方法三 Class.forName()方…...
wordpress相册打造的视频弹出/如何制作个人网站
首款骁龙870平板官宣:联想小新平板 5月25日 见预热了许久的联想小新平板,终于揭开了神秘的面纱,联想小新官博昨天发布官宣消息:真香价 5月25日 19:30分 平板发布会见。根据联想小新官博预热来看,此次发布会…...
做网站如何突出网站特色/百度收录要多久
CentOS5、6系统的启动流程基于Intel X86架构平台的系统启动流程:1.POST:Power-On Self Testing,加电自检;CMOS:在这里面有一个EPROM,可擦写可编程的只读存储器;在这里面保存了一小段程序叫做BIO…...
wordpress 主题重置/千锋教育地址
下面的代码是涉及图像的非常简单的测试.每当我向System.in发送“ a”时,它应该重新绘制图像,而当我发送“ q”时,它应该退出程序.问题在于只有出口有效:永远不会调用paint()方法,我也不为什么.我检查了对“ super.paint()”的调用,尝试用paintCompoenent(Graphics g…...