当前位置: 首页 > news >正文

设计模式-责任链模式

责任链模式

请求发送者和接收者连接成一条链,一个对象处理完,交给下一位,沿着链传递请求,这就是责任链模式。

角色

  • 抽象处理者(Handler)
    定义了处理请求的方法
  • 具体处理者(ContreteHandler)
    包含下一个抽象处理者作为成员变量,不同的处理者实现不同的处理逻辑,处理完了就交给下一个

案例

数据检查者

在使用前端给后端传入的数据前,都需要做校验,比如数据完整性校验等等。一个一个 if-else 写起来比较麻烦,请使用责任链模式优化代码编写体验。

工具类

Mapx

import java.util.HashMap;public class Mapx<K, V> extends HashMap<K, V> {public static Mapx init(String key, Object value) {return new Mapx().set(key,value);}public Mapx<K, V> set(K key, V value){this.put(key, value);return this;}
}

Setx

import java.util.HashSet;public class Setx extends HashSet {public static Setx init(Object obj){return new Setx().set(obj);}public Setx set(Object obj){this.add(obj);return this;}
}

Res:REST接口返回格式生成器

import java.util.Map;public class Res {public static Map ok(String msg, int symbol, Object data) {return Mapx.init("code",200).set("symbol",symbol).set("data",data).set("type","ok");}public static Map fail(String msg, int symbol, Object data) {return Mapx.init("code",400).set("symbol",symbol).set("data",data).set("type","fail");}
}

Checker:抽象处理者

import java.util.Map;
import java.util.Set;public interface Checker {public Checker hint(String hint);public Checker symbol(int symbol);public Checker ignore(Object ign);public Map check();public Checker next(Checker nextChecker);}

CompleteChecker:完整性检查者

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;public class CompleteChecker implements Checker{private Object suspicion;private String hint;private int symbol;private Set ign;private Checker nextChecker;public CompleteChecker(Object suspicion) {this.suspicion = suspicion;}@Overridepublic Checker hint(String hint) {this.hint = hint;return this;}@Overridepublic Checker symbol(int symbol) {this.symbol = symbol;return this;}@Overridepublic Map check() {String result = this.is_complete(suspicion, ign);if (result!=null){Map data = Mapx.init("field", result);return Res.fail(hint, symbol, data);}if (nextChecker!=null){return nextChecker.check();}return null;}@Overridepublic Checker next(Checker nextChecker) {this.nextChecker = nextChecker;return nextChecker;}public CompleteChecker ignore(Object ign){Set ignx = (Set) ign;this.ign = ignx;return this;}private String is_complete(Object obj, Set<String> ign){if(obj==null){return "Self";}if(ign==null){ign = new HashSet<>();}Field[] fields = obj.getClass().getDeclaredFields();Boolean rs = true;for (Field field : fields) {field.setAccessible(true);Object fieldValue = null;String fieldName = "";Type fieldType = null;try {fieldValue = field.get(obj); //得到属性值fieldType = field.getGenericType();//得到属性类型fieldName = field.getName(); // 得到属性名
//                System.out.println("属性类型:" + fieldType.getTypeName() + ",属性名:" + fieldName + ",属性值:" + fieldValue);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}if(ign.contains(fieldName)){// System.out.println(fieldName+" 属性忽略检测");continue;}if (fieldValue == null || fieldValue.equals("")) {  //只要有一个属性值不为null 就返回false 表示对象不为null
//                System.out.println("检测的成员变量中有空值");
//                System.out.println(fieldName + "为空");
//                System.out.println(fieldName + ": " + fieldValue);return fieldName;}// 如果成员是列表if (fieldValue instanceof java.util.List) {if (((List<?>) fieldValue).size()==0){return fieldName;}}}return null;}
}

Main

public class Main {public static void main(String[] args) {User user = new User("小靳", "female", 20,new User("父亲","male",50,new User("爷爷", "male", 70, null)));Checker checker = new CompleteChecker(user).ignore(Setx.init("age")).hint("user不完整");checker.next(new CompleteChecker(user.father)).ignore(Setx.init("age")).hint("father不完整").next(new CompleteChecker(user.father.father)).ignore(Setx.init("age")).hint("grandfather不完整");System.out.println("检测结果: " + checker.check());}
}

Output:

检测结果: {msg=grandfather不完整, symbol=0, code=400, data={field=father}, type=fail}

当然,我这个案例的代码实现存在漏洞,user.father为null的时候,user.father.father是取不到的。


责任链模式的优缺点

优点

  • 使得一个对象无需知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,且链式结构由客户端创建 => 降低了系统的耦合度
  • 在系统中增加一个新的具体处理者无须修改原有系统源代码,只需要在客户端重新建立链式结构即可 => 符合开闭原则

缺点

  • 由于一个请求没有一个明确地接受者 => 无法保证它一定会被处理
  • 对于较长的职责链 => 系统性能有一定影响且不利于调试
  • 如果建立链不当,可能会造成循环调用 => 导致系统进入死循环

应用场景

  • 有多个对象处理同一个请求且无需关心请求的处理对象时谁以及它是如何处理的 => 比如各种审批流程
  • 可以动态地指定一组对象处理请求,客户端可以动态创建职责链来处理请求,还可以改变链中处理者之间的先后次序 => 比如各种流程定制

相关文章:

设计模式-责任链模式

责任链模式 请求发送者和接收者连接成一条链&#xff0c;一个对象处理完&#xff0c;交给下一位&#xff0c;沿着链传递请求&#xff0c;这就是责任链模式。 角色 抽象处理者&#xff08;Handler&#xff09; 定义了处理请求的方法具体处理者&#xff08;ContreteHandler&am…...

不变的是需求,变化的是解决方法和工具:探讨iPaaS与ESB的差异

在企业数字化转型过程中&#xff0c;企业需要面临日益复杂的业务和数据集成挑战。为了应对这些挑战&#xff0c;需要借助适当的解决方法和工具来实现系统间的通信和数据传输。在这方面&#xff0c;iPaaS&#xff08;Integration Platform as a Service&#xff09;和ESB&#x…...

网络解析----faster rcnn

Faster R-CNN&#xff08;Region-based Convolutional Neural Network&#xff09;是一种基于区域的卷积神经网络用于目标检测任务的模型。它是一种两阶段的目标检测方法&#xff0c;主要包含以下几个步骤&#xff1a; Region Proposal Network&#xff08;RPN&#xff09;: F…...

modbus TCP协议讲解及实操

具体讲解 前言正文modbus tcp主机请求数据基本讲解Modbus Poll工具简单使用讲解 modbus tcp从机响应数据Modbus Slave工具简单使用讲解 前言 关于modbus tcp从0到1的讲解&#xff0c;案例结合讲解&#xff0c;详细了解整个modbus的可以参考这个&#xff1a;详解Modbus通信协议…...

既有内销又有外贸,多样性外贸业务管理解决方案

随着外贸数字化贸易全球化的深入发展&#xff0c;出口、进口、内销业务越来越受到关注。外贸业务是企业在海外市场进行商品贸易&#xff0c;而内销业务是企业在国内市场进行商品贸易。在管理这种业务时&#xff0c;想要实现降本增效&#xff0c;企业需要有一套成熟的管理解决方…...

spring eurake中使用IP注册

在开发spring cloud的时候遇到一个很奇葩的问题&#xff0c;就是服务向spring eureka中注册实例的时候使用的是机器名&#xff0c;然后出现localhost、xxx.xx等这样的内容&#xff0c;如下图&#xff1a; eureka.instance.perferIpAddresstrue 我不知道这朋友用的什么spring c…...

c# 从零到精通 form界面之listView控件

c# c# 从零到精通 form界面之listView控件 添加值 设置值 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace Test06 { public partial cla…...

Qt6.5.1+WebRTC学习笔记(十二)环境搭建流媒体服务器(ubuntu22.04+SRS)

前言 若只是实现一对一通信&#xff0c;仅使用webrtc就足够了。但有时间需要进行多个人的直播会议&#xff0c;当人比较多时&#xff0c;建议使用一个流媒体服务器&#xff0c;笔者使用的是SRS。 这个开源项目资料比较全&#xff0c;笔者仅在此记录下搭建过程 一、准备 1.操…...

LeetCode 9. 回文数

LeetCode 9. 回文数 一、题目描述&#xff1a; 给你一个整数 x &#xff0c;如果 x 是一个回文整数&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 回文数是指正序&#xff08;从左向右&#xff09;和倒序&#xff08;从右向左&#xff09;读都是一样的整数…...

Linux系统之部署Teleport堡垒机系统

Linux系统之部署Teleport堡垒机系统 一、Teleport介绍1.1 Teleport简介1.2 Teleport特点1.3 支持操作系统 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本 四、部署teleport服务端4.1 创建部署目录4.2 下载t…...

【二叉树part02】| 102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树

目录 ✿LeetCode102.二叉树的层序遍历❀ ✿LeetCode226.翻转二叉树❀ ✿LeetCode101.对称二叉树❀ ✿LeetCode102.二叉树的层序遍历❀ 链接&#xff1a;102.二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff…...

【干货】Android系统定制基础篇:第十五部分(Android支持鼠标右键返回、GPIO 控制方案、属性标识USB摄像头的VID与PID)

1、修改 frameworks/native/services/inputflinger/InputReader.cpp 如下&#xff1a; diff --git a/frameworks/native/services/inputflinger/InputReader.cpp b/frameworks/native/services/inputflinger/Inp index 7207a83..2721800 100755 --- a/frameworks/native/servi…...

ubuntu18 修改dns服务器地址为google

域名解析被干扰的有点严重&#xff0c;直接使用谷歌dns服务器来解析ip 第一、永久修改DNS方法 1、修改 /etc/systemd/resolved.conf 文件 vi /etc/systemd/resolved.conf这里我们可以看到这些参数&#xff1a; # 指定 DNS 服务器&#xff0c;以空白分隔&#xff0c;支持 IP…...

RHCE shell 作业一

1. 设置邮箱 [rootserver ~]# yum install s-nail -y [rootserver ~]# vim /etc/s-nail.rc 编写脚本 [rootserver ~]# vim homework1.sh 设置定时任务 [rootserver ~]# vim /etc/crontab 2. [rootserver ~]# vim homework2.sh 测试&#xff1a; 3. [rootserve…...

Qqis中采用栅格工具生成XYZ瓦片(目录)简介

目录 前言 一、Qgis的相关功能 1、数据准备 2、将两个xyz图源添加到图层 二、Qgis栅格工具生成 1、生成xyz图块工具在哪里 2、生成xyz图块怎么用 3、下载结果 4、Leaflet加载离线瓦块 总结 前言 在上一篇博客中&#xff0c;介绍了一种在Qgis中基于QMetaTiles插件进行xyz瓦…...

【Axure教程】根据标签数自动调整尺寸的多选下拉列表

​多选下拉列表常用于需要用户从一组选项中选择多个选项的情况。它提供了一个下拉菜单&#xff0c;用户可以点击展开并选择他们感兴趣的多个选项。多选下拉列表可以用于展示可选标签&#xff0c;并允许用户选择多个标签。例如&#xff0c;在一个博客发布界面上&#xff0c;可以…...

【python】js逆向基础案例——有道翻译

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 课程亮点: 1、爬虫的基本流程 2、反爬的基本原理 3、nodejs的使用 4、抠代码基本思路 环境介绍: python 3.8 pycharm 2022专业版 >>> 免费使用教程文末名片获取 requests >>> pip install req…...

面经系列.飞猪 Java开发工程师.杭州.2023.6.14一面面经

本人是2023年6月14日面试的,面试的岗位是飞猪的Java研发工程师,地点是杭州,面试时长37分钟,没有问八股文。全都围绕项目在问,在提问的过程中会涉及到原理以及具体操作。整体面试感觉下来,面试官很随和,通过面试也能和面试官学到很多,交流了对未来行业的看法,也对某些技…...

基于物联网及云平台的光伏运维系统

系统结构 在光伏变电站安装逆变器、以及多功能电力计量仪表&#xff0c;通过网关将采集的数据上传至服务器&#xff0c;并将数据进行集中存储管理。用户可以通过PC访问平台&#xff0c;及时获取分布式光伏电站的运行情况以及各逆变器运行状况。平台整体结构如图所示。 光伏背景…...

Android kotlin 实现仿京东多个item向左自动排队(横向、动手滑动、没有首尾滑动)功能

文章目录 一、实现效果二、引入依赖三、源码实现1、适配器2、视图实现一、实现效果 二、引入依赖 在app的build.gradle在添加以下代码 1、implementation com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6,这个里面带的适配器,直接调用就即可 BaseRecyclerViewAdapt…...

美团买菜基于 Flink 的实时数仓建设

美团买菜基于 Flink 的实时数仓建设 1. 背景介绍2. 技术愿景和架构设计3. 典型场景、挑战与应对3.1 动态 ETA 实时特征3.2 实时数据经营分析 4. 未来规划 1. 背景介绍 美团买菜是美团自营生鲜零售平台&#xff0c;上面所有的商品都由美团亲自采购&#xff0c;并通过供应链物流体…...

前端vue入门(纯代码)08

【08.webStorage--本地存储】 (1). 什么是 localStorage 和 sessionStorage &#xff1f; 它们都是浏览器的一种本地存储数据的方式它们只是存在本地&#xff0c;即浏览器中&#xff0c;不会发送到服务器 它们的区别&#xff1a; localStorage&#xff1a;永久存在浏览器中…...

Xubuntu22.04之便签工具(一百八十)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

Unity入门4——重要组件与API

一、GameObject &#xff08;一&#xff09;成员变量 // 名字 print(this.gameObject.name); this.gameObject.name "Lesson4唐老狮改名"; print(this.gameOb…...

NFS服务器安装及NFS制备程序安装

NFS服务器安装及NFS制备程序安装 NFS服务器安装 NFS是一种分布式文件系统协议&#xff0c;由sun公司开发&#xff0c;旨在允许客户端主机可以像访问本地存储一样通过网络访问服务端文件 安装NFS服务器 登录需要安装NFS服务器的主机执行以下命令完成NFS安装 yum -y install…...

matlab+yalmip+cplex求解车辆路径优化问题(VRP)--matlab中yalmip函数介绍

YALMIP是一个MATLAB工具箱&#xff0c;用于建模和求解优化问题。它支持线性规划、二次规划、整数规划、鲁棒优化、半定规划等优化问题的建模和求解。下面是一些常用的函数的详细介绍&#xff1a; 1. sdpvar&#xff1a;用于定义优化问题中的变量。可以定义实数、向量和矩阵型变…...

实战:用dockerfile创建镜像实现springboot项目容器化

文章目录 前言技术积累docker基本操作命令dockerfile简介dockerfile指令说明 实战演示创建dockerfile创建挂载目录构建dockerfile启动容器完成验证 写在最后 前言 docker容器化方案是当下流行的服务部署方式&#xff0c;在软件领域举足轻重。我公司的测试、线上环境都采用dock…...

【Flask】配置项解析与加载

文章目录 默认配置表配置项加载方式直接配置存放在app.config字典通过.py配置文件通过class类加载对象通过.json配置文件通过环境变量配置内置命令行 默认配置表 配置项默认值备注DEBUGFalse是否开启 Debug 模式。如果为True&#xff0c;修改了代码&#xff0c;只需要保存&…...

Dinky: 实时即未来,让 Flink SQL 纵享丝滑--如何本地编译、运行

什么是Dinky 实时即未来,Dinky 为 Apache Flink 而生,让 Flink SQL 纵享丝滑。 Dinky 是一个开箱即用、易扩展,以 Apache Flink 为基础,连接 OLAP 和数据湖等众多框架的一站式实时计算平台,致力于流批一体和湖仓一体的探索与实践。 最后,Dinky 的发展皆归功于 Apache …...

2023 Nature 健康系统规模的语言模型是通用预测引擎

文章目录 一、论文关键信息二、论文主要内容三、总结与讨论🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 一、论文关键信息 论文标题:Health system-scale language models are all-purpose prediction engines 期刊信息:2023 Nature 论文地址:h...

珠海网站策划公司/最新的域名网站

python十六进制字符串To assign a hexadecimal value in the string so that it can be printed as a string, we use \x that is known as Escape sequence”, it represents that given value is the hexadecimal value. 为了在字符串中分配一个十六进制值以便可以将其打印为…...

天安节能科技园公司做网站/最新实时新闻

给定一个数组 nums 和一个值 val&#xff0c;你需要原地移除所有数值等于 val 的元素&#xff0c;返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 元素的顺序可以改变。你不需要考虑数组中超出新…...

合肥企业网站建设工作室/网络推广的基本渠道

本次实验主要是实现站点间的复制实验&#xff0c;实验图如下&#xff1a; 1&#xff09;构建好上图的域结构以后&#xff0c;打开192.168.10.2服务器的AD站点和服务&#xff0c;可以看到站点间的默认关系。 2&#xff09;右击Sites---》新建---》站点。分别输入XM和FZ做为站点的…...

59网站一起做网店广州/在线建站网页制作网站建设平台

SimpleDateFormat转24小时类型时间字符串&#xff1a;yyyy-MM-dd HH:mm:ss...

wordpress backup to dropbox/中小企业管理培训课程

目录 一、前后端使用架构导致 二、开发人员经验问题/思维严谨性导致 三、业务特点导致 四、测试人员的经验缺乏导致 五、迭代周期不合理导致 六、上下游业务严重耦合导致 前言 产生bug的具体原因或许多种多样&#xff0c;但在bug原因分析过程中&#xff0c;希望能抽丝剥茧…...

公司年前做网站好处/网站检测中心

单线程在好些年前的MS-DOS时代&#xff0c;操作系统处理问题都是单任务的&#xff0c;我想做听音乐和看电影两件事儿&#xff0c;那么一定要先排一下顺序。(好吧&#xff01;我们不纠结在DOS时代是否有听音乐和看影的应用。^_^)from time import ctime,sleepdef music():for i …...