当前位置: 首页 > 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是取不到的。


责任链模式的优缺点

优点

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

缺点

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

应用场景

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

相关文章:

  • 不变的是需求,变化的是解决方法和工具:探讨iPaaS与ESB的差异
  • 网络解析----faster rcnn
  • modbus TCP协议讲解及实操
  • 既有内销又有外贸,多样性外贸业务管理解决方案
  • spring eurake中使用IP注册
  • c# 从零到精通 form界面之listView控件
  • Qt6.5.1+WebRTC学习笔记(十二)环境搭建流媒体服务器(ubuntu22.04+SRS)
  • LeetCode 9. 回文数
  • Linux系统之部署Teleport堡垒机系统
  • 【二叉树part02】| 102.二叉树的层序遍历、226.翻转二叉树、101.对称二叉树
  • 【干货】Android系统定制基础篇:第十五部分(Android支持鼠标右键返回、GPIO 控制方案、属性标识USB摄像头的VID与PID)
  • ubuntu18 修改dns服务器地址为google
  • RHCE shell 作业一
  • Qqis中采用栅格工具生成XYZ瓦片(目录)简介
  • 【Axure教程】根据标签数自动调整尺寸的多选下拉列表
  • 【python】js逆向基础案例——有道翻译
  • 面经系列.飞猪 Java开发工程师.杭州.2023.6.14一面面经
  • 基于物联网及云平台的光伏运维系统
  • Android kotlin 实现仿京东多个item向左自动排队(横向、动手滑动、没有首尾滑动)功能
  • 美团买菜基于 Flink 的实时数仓建设
  • 前端vue入门(纯代码)08
  • Xubuntu22.04之便签工具(一百八十)
  • Unity入门4——重要组件与API
  • NFS服务器安装及NFS制备程序安装
  • matlab+yalmip+cplex求解车辆路径优化问题(VRP)--matlab中yalmip函数介绍
  • 实战:用dockerfile创建镜像实现springboot项目容器化
  • 【Flask】配置项解析与加载
  • Dinky: 实时即未来,让 Flink SQL 纵享丝滑--如何本地编译、运行
  • 2023 Nature 健康系统规模的语言模型是通用预测引擎
  • 《2023 年 React 生态》