设计模式——责任链模式

责任链模式

定义

使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有对象处理它为止。

优缺点

优点

能将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌,两者解耦提高系统的灵活性

缺点

  1. 性能问题,每个请求都是从链头遍历到链尾,尤其是链较长的时候,会有性能方面的影响。
  2. 调试不方便,由于采用了类似递归的方式(本实验用的是队列的遍历),调试的时候会比较复杂。

实验小结

  1. 即一个任务到来时,进入责任链,从头开始遍历责任人,不是则依次往下寻找,直到找到负责该任务的责任人(可能无人负责)
  2. 将责任链节点依次加入队列就能build()出责任链关系。

代码模拟场景

项目进入测试阶段,项目组出现问题,依次寻找测试、开发、产品经理寻求帮助。

责任链模式

UML图

在这里插入图片描述

责任链节点抽象、实现类

public abstract class AbstractHandler {/*** 测试处理等级*/public final static int TEST_LEVEL_REQUEST = 1;/*** 开发处理等级*/public final static int DEVELOPER_LEVEL_REQUEST = 2;/*** 产品经理处理等级*/public final static int PRODUCT_MANAGER_LEVEL_REQUEST = 3;/*** 能处理的级别*/private final int level;/*** 责任传递,下个责任人是谁*/private AbstractHandler nextHandler;/*** 每个责任节点都要说明下自己能处理哪些需求** @param level 处理等级*/public AbstractHandler(int level) {this.level = level;}/*** 处理项目的要求** @param project 项目需要*/public final void handleMessage(IProject project) {if (project.getType() == this.level) {this.response(project);} else {// 后续有环节则继续推进请求if (this.nextHandler != null) {this.nextHandler.handleMessage(project);} else {System.out.println("已无流程批示,不同意");}}}/*** 传递给下个处理人** @param handler 下个处理人*/public void setNext(AbstractHandler handler) {this.nextHandler = handler;}/*** 处理人的回应** @param project 项目对象*/protected abstract void response(IProject project);
}/*** @author Evad.Wu* @Description 测试工程师* @date 2023-07-10*/
public class TestEngineer extends AbstractHandler {/*** 每个责任节点都要说明下自己能处理哪些需求*/public TestEngineer() {super(AbstractHandler.TEST_LEVEL_REQUEST);}@Overrideprotected void response(IProject project) {System.out.println("项目组向测试人员咨询");System.out.println(project.getRequest());System.out.println("测试人员的答复是:找我就对了");}
}/*** @author Evad.Wu* @Description 开发工程师* @date 2023-07-10*/
public class DevelopmentEngineer extends AbstractHandler {/*** 每个责任节点都要说明下自己能处理哪些需求*/public DevelopmentEngineer() {super(AbstractHandler.DEVELOPER_LEVEL_REQUEST);}@Overrideprotected void response(IProject project) {System.out.println("项目组向开发人员咨询");System.out.println(project.getRequest());System.out.println("开发人员的答复是:找我就对了");}
}/*** @author Evad.Wu* @Description 产品经理* @date 2023-07-10*/
public class ProductManager extends AbstractHandler {/*** 每个责任节点都要说明下自己能处理哪些需求*/public ProductManager() {super(AbstractHandler.PRODUCT_MANAGER_LEVEL_REQUEST);}@Overrideprotected void response(IProject project) {System.out.println("项目组向产品经理咨询");System.out.println(project.getRequest());System.out.println("产品经理的答复是:找我就对了");}
}

项目组抽象、实现类

public interface IProject {/*** 获取咨询问题的类型** @return 类型编号*/int getType();/*** 获取咨询的内容** @return 咨询的内容*/String getRequest();
}public class ProjectImpl implements IProject {/*** 问题类型* 1-测试处理 2-开发处理 3-产品处理*/private final int type;/*** 本次处理的请求*/private String request;public ProjectImpl(int type, String request) {this.type = type;this.request = request;switch (this.type) {case 1 -> this.request += "测试方面的咨询";case 2 -> this.request += "开发方面的咨询";case 3 -> this.request += "产品方面的咨询";default -> this.request += "没有人对应的人员可以处理";}}/*** 获取咨询问题的类型** @return 类型编号*/public int getType() {return type;}/*** 获取咨询的内容** @return 咨询的内容*/public String getRequest() {return request;}
}

责任链

负责将节点串联起来

public class Chain<T extends AbstractHandler> {// 定义三个咨询对象private AbstractHandler peek;public Chain(Queue<T> sequence) {if (!sequence.isEmpty()) {T peek = sequence.peek();this.peek = peek;sequence.poll();for (T current : sequence) {peek.setNext(current);peek = current;}}}public AbstractHandler build() {return peek;}
}

入口类

public class ResponsibilityChainMain {public static void main(String[] args) {List<IProject> projectList = new ArrayList<>();projectList.add(new ProjectImpl(1, "项目出问题,需要人员支持..."));projectList.add(new ProjectImpl(2, "项目出问题,需要人员支持..."));projectList.add(new ProjectImpl(3, "项目出问题,需要人员支持..."));projectList.add(new ProjectImpl(4, "项目出问题,需要人员支持..."));Queue<AbstractHandler> sequence = new LinkedList<>();// 咨询的顺序是:测试、开发、产品经理sequence.add(new TestEngineer());sequence.add(new DevelopmentEngineer());sequence.add(new ProductManager());AbstractHandler handler = new Chain<>(sequence).build();for (IProject project : projectList) {handler.handleMessage(project);System.out.println();}}
}

结果

在这里插入图片描述

参考书籍

秦小波《设计模式之禅》

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

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

相关文章

Java设计模式之结构型-代理模式(UML类图+案例分析)

目录 一、基础概念 二、UML类图 1、静态代理类图 2、动态代理类图 三、角色设计 四、案例分析 1、静态代理 2、JDK动态代理 3、Cglib动态代理 五、总结 一、基础概念 代理模式是一种结构型设计模式&#xff0c;它用一个代理对象来封装一个目标对象&#xff0c;通常…

Python+docx实现python对word文档的编辑

前言&#xff1a; 该模块可以通过python代码来对word文档进行大批量的编辑。docx它提供了一组功能丰富的函数和方法&#xff0c;用于创建、修改和读取Word文档。下面是docx模块中一些常用的函数和方法的介绍&#xff1a; 安装&#xff1a;pip install docx 一、准备一个word文档…

MYSQL执行一条SELECT语句的具体流程

昨天CSDN突然抽风 我一个ctrlz把整篇文章给撤掉了还不能复原 直接心态崩了不想写了 不过这部分果然还是很重要,还是写出来吧 流程图 这里面总共有两层结构Server层 储存引擎 Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现&#xff0c;主要包…

WebSocket理解

WebSocket理解 WebSocket定义与HTTP关系相同点:不同点&#xff1a;联系总体过程 HTTP问题长轮询Ajax轮询 WebSocket特点 WebSocket 定义 本质上是TCP的协议 持久化的协议 实现了浏览器和服务器的全双工通信&#xff0c;能更好的节省服务器资源和带宽 与HTTP关系 相同点: 基于…

【bug】flameshot在ubuntu上的4K屏幕,双屏幕上用不了截图

问题 直接在4K屏幕上运行flameshot截图&#xff0c;直接黑屏 主屏 &#xff1a;4K 副屏&#xff1a;2k 解决 2.1长按1-2秒开机键&#xff0c;先回到桌面。 2.2 设置主屏缩放为125% 2.3 设置键盘快捷键命令为env QT_AUTO_SCREEN_SCALE_FACTOR1 flameshot gui 替代flameshot的…

zeppelin的hive使用

zeppelin的hive使用 配置项 default.driver org.apache.hive.jdbc.HiveDriver default.url jdbc:hive2://192.168.xxx.xxx:10000 default.user hiveHive使用&#xff1a;点击create new note Default Interpreter选择hive

动态表单实现原理

目录 动态表单是什么 动态表单的关键 前后端职责 数据库与表结构 功能实现与改进建议 动态表单是什么 静态表单是很常见&#xff0c;也是常规做法&#xff0c;其表单的结构是固定的&#xff0c;通常情况下一个表单对应数据库的一张表&#xff0c;表单中一个数据项对应数据表的一…

idea创建webapp文件夹

结果的图片&#xff1a; 第一步&#xff1a; file-》project structure 第二步&#xff1a; 修改路径&#xff0c;点击右侧“Deloyment descriptors”下面的笔进行修改。 // 增加了src\main // web修改为了webapp C:\Users\www12\Desktop\huwantiku2\src\main\webapp\WEB-IN…

【Java】JVM执行流程、类加载过程和垃圾回收机制

JVM执行流程执行引擎本地方法接口运行时数据区方法区堆虚拟机栈(线程私有)本地方法栈(线程私有)程序计数器(线程私有) 堆溢出问题类加载类加载的过程加载连接验证准备解析 初始化 双亲委派机制 垃圾回收死亡对象的判断算法引用计数算法可达性分析算法 垃圾回收的过程标记-清除算…

Linux常用命令——emacs命令

在线Linux命令查询工具 emacs 功能强大的全屏文本编辑器 补充说明 emacs命令是由GNU组织的创始人Richard Stallman开发的一个功能强大的全屏文本编辑器&#xff0c;它支持多种编程语言&#xff0c;具有很多优良的特性。有众多的系统管理员和软件开发者使用emacs。 语法 e…

C语言动态获取设备的网络接口名称和状态以及对应的IP地址

一、目的 在实际项目中需要获取设备的IP地址然后通过广播的形式通知局域网内的其他设备。 二、介绍 方法一 通过ioctl方式获取SIOCGIFADDR信息 /** C Program to Get IP Address*/ #include <stdio.h> #include <string.h> #include <sys/types.h> #includ…

【数学建模】统计分析方法

文章目录 1.回归分析2. 逻辑回归3. 聚类分析4. 判别分析5. 主成分分析6. 因子分析7. 对应分析 1.回归分析 数据量要多&#xff0c;样本总量n越大越好——>保证拟合效果更好&#xff0c;预测效果越好 一般n>40/45较好 方法 建立回归模型 yiβ0β1i……βkxkiεi 所估计的…