设计模式之责任链模式

        责任链模式是一种经典的设计模式,属于行为型设计模式,他的核心思想是:将请求的发起者与接受者进行解耦,让多个对象都有机会处理请求,从而避免了请求发送者与接受者之间的耦合关系。这些对象连接形成一条链,请求沿着这条链传递,直到被某个对象处理为止。

        你会简单的发现,在这种处理模式直线,实际上是有先后顺序的,你可以把它想象成为一个链表,从头到尾开始进行执行,在某一步执行完毕之后结束返回,下面我将举一个具体的业务场景来具体说明当前模式

业务场景

        我们需要计算一下两个地点的运费,但是对于每个地点的运费的计算规则是不同的,也就是我们现在设计了多个模板,你需要进行判断然后返回需要的模板,下面给出逻辑示意图

解决

        你会发现当我们给出逻辑示意图的时候,整个思路就比较明确了,你可以写许多的ifelse,但是这样的话你的代码会显得比较冗余并且拓展性极差,所以我们基于任务链设计模式来解决

首先,我们定义抽象类处理链对象,你可以认为实际上就是指向下一个的指针,也就是说,当你的是否同城判断完之后,如果成功就返回,不成功就执行下一个节点

package com.sl.ms.carriage.handler;import com.sl.ms.carriage.domain.dto.WaybillDTO;
import com.sl.ms.carriage.entity.CarriageEntity;/*** 运费模板处理链的抽象定义*/
public abstract class AbstractCarriageChainHandler {private AbstractCarriageChainHandler nextHandler;/*** 执行过滤方法,通过输入参数查找运费模板** @param waybillDTO 输入参数* @return 运费模板*/public abstract CarriageEntity doHandler(WaybillDTO waybillDTO);/*** 执行下一个处理器** @param waybillDTO     输入参数* @param carriageEntity 上个handler处理得到的对象* @return*/protected CarriageEntity doNextHandler(WaybillDTO waybillDTO, CarriageEntity carriageEntity) {if (nextHandler == null || carriageEntity != null) {//如果下游Handler为空 或 上个Handler已经找到运费模板就返回return carriageEntity;}return nextHandler.doHandler(waybillDTO);}/*** 设置下游Handler** @param nextHandler 下游Handler*/public void setNextHandler(AbstractCarriageChainHandler nextHandler) {this.nextHandler = nextHandler;}
}

然后,你这个时候就是去定义同城,同省,同经济区的既可

这边写一个同城的

package com.sl.ms.carriage.handler;import com.sl.ms.carriage.domain.constant.CarriageConstant;
import com.sl.ms.carriage.domain.dto.WaybillDTO;
import com.sl.ms.carriage.entity.CarriageEntity;
import com.sl.ms.carriage.service.CarriageService;
import com.sl.transport.common.util.ObjectUtil;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import javax.annotation.Resource;/*** 同城寄*/
@Order(100) //定义顺序
@Component
public class SameCityChainHandler extends AbstractCarriageChainHandler {@Resourceprivate CarriageService carriageService;@Overridepublic CarriageEntity doHandler(WaybillDTO waybillDTO) {CarriageEntity carriageEntity = null;if (ObjectUtil.equals(waybillDTO.getReceiverCityId(), waybillDTO.getSenderCityId())) {//同城carriageEntity = this.carriageService.findByTemplateType(CarriageConstant.SAME_CITY);}return doNextHandler(waybillDTO, carriageEntity);}
}

你会发现,这里我们在最后在一次调用了doNextHandler,也就是传给了下一个节点,

这个时候开始组装处理链

package com.sl.ms.carriage.handler;import cn.hutool.core.collection.CollUtil;
import com.sl.ms.carriage.domain.dto.WaybillDTO;
import com.sl.ms.carriage.entity.CarriageEntity;
import com.sl.transport.common.exception.SLException;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;/*** 查找运费模板处理链 @Order注解指定handler顺序*/
@Component
public class CarriageChainHandler {/*** 利用Spring注入特性,按照 @Order 从小到达排序注入到集合中*/@Resourceprivate List<AbstractCarriageChainHandler> chainHandlers;private AbstractCarriageChainHandler firstHandler;/*** 组装处理链*/@PostConstructprivate void constructChain() {if (CollUtil.isEmpty(chainHandlers)) {throw new SLException("not found carriage chain handler!");}//处理链中第一个节点firstHandler = chainHandlers.get(0);for (int i = 0; i < chainHandlers.size(); i++) {if (i == chainHandlers.size() - 1) {//最后一个处理链节点chainHandlers.get(i).setNextHandler(null);} else {//设置下游节点chainHandlers.get(i).setNextHandler(chainHandlers.get(i + 1));}}}public CarriageEntity findCarriage(WaybillDTO waybillDTO) {//从第一个节点开始处理return firstHandler.doHandler(waybillDTO);}}

我们对于最后一个节点的下一个节点设置为null,对于每个节点的下一个节点,我们实际上是由先后顺序的,我们可以基于spring对于每一个类写上order注解进行排序,spring的抽象类在进行注入的时候,会根据order的值从小到大注入,这样我们之后调用find方法就可以解决当前的业务问题了

总结

  • 责任链模式是一种行为型设计模式,用于解耦请求发送者和接收者。
  • 核心思想​:将多个处理者连接成一条链,请求沿着链传递,直到被某个处理者处理。
  • 适用场景​:Web 过滤器、审批流程、异常处理、日志记录等。
  • 优点​:解耦、灵活、符合单一职责原则。
  • 缺点​:请求可能未被处理,调试较复杂。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用YOLO模型进行线程安全推理

概述 在多线程环境中运行YOLO 模型时需要特别注意线程安全问题。Python threading 模块允许同时运行多个线程&#xff0c;但在这些线程中使用YOLO 模型时&#xff0c;需要注意一些重要的安全问题。 Python 线程是一种并行计算形式&#xff0c;允许程序同时运行多个操作。不过…

对抗性提示:进阶守护大语言模型

人工智能模型正快速进化 —— 变得更具帮助性、更流畅&#xff0c;并且更深入地融入我们的日常生活和商业运营中。但随着其能力的提升&#xff0c;风险也在增加。在维护安全可信的人工智能方面&#xff0c;最紧迫的挑战之一是对抗性提示&#xff1a;这是一种微妙且通常富有创意…

RNN为什么不适合大语言模型

在自然语言处理&#xff08;NLP&#xff09;领域中&#xff0c;循环神经网络&#xff08;RNN&#xff09;及衍生架构&#xff08;如LSTM&#xff09;采用序列依序计算的模式&#xff0c;这种模式之所以“限制了计算机并行计算能力”&#xff0c;核心原因在于其时序依赖的特性&a…

C语言中errno错误码定义及使用

一.概述 1.介绍 在 C 语言中&#xff0c;errno是一个用于标识程序运行时错误的全局变量。当系统调用或库函数执行失败时&#xff0c;通常会设置errno以指示具体的错误类型。 2.errno的基本定义 头文件&#xff1a;#include <errno.h> 类型&#xff1a;int 用途&#x…

电阻、电容、电感

目录 前言一、电阻1.阻值识别 二、电容1.注意事项2.电容特性3.相对电压不能突变4.储能特性5.稳定电压&#xff08;滤波&#xff09;6.容抗7.低通滤波RC8.高通滤波CR 三、电感1.特性2.注意事项3.感抗4.低通滤波LR5.高通滤波RL6.疑问 四、LC低通滤波 前言 基础知识可以看个人笔记…

Docker学习笔记:数据卷

本文是自己的学习笔记 1、数据卷基本概念2、数据卷示例3、数据卷的权限控制4、数据卷的创建方式5、数据卷容器 1、数据卷基本概念 数据卷就是docker容器产生的数据&#xff0c;如果不通过docker commit生成新的镜像&#xff0c;使得数据做为镜像的一部分保存下来&#xff0c;那…

内存泄漏到底是个什么东西?如何避免内存泄漏

目录 内存泄漏到底是个什么东西&#xff1f;如何避免内存泄漏 一、什么是内存泄漏&#xff1f; 1、内存泄漏 2、GC&#xff08;垃圾回收&#xff09;机制是什么&#xff1f; 二、常见内存泄漏场景 1、意外的全局变量 2、被遗忘的定时器/回调 3、闭包未释放大对象 4、D…

【图像处理入门】8. 数学基础与优化:线性代数、概率与算法调优实战

摘要 图像处理的核心离不开数学工具的支撑。本文将深入解析线性代数、概率论在图像领域的应用,包括矩阵变换与图像几何操作的关系、噪声模型的数学描述,以及遗传算法、粒子群优化等智能算法在参数调优中的实践。通过理论结合代码案例,帮助读者掌握从数学原理到工程优化的完…

包含30个APP客户端UI界面的psd适用于旅游酒店项目

包含30个APP客户端UI界面的psd适用于旅游酒店项目 此资源包含30个完全可编辑的psd界面组成。内容包括欢迎页、登录、注册、首页、搜索、侧边菜单、用户中心、个人介绍、用户空间、产品详细信息、酒店预定、天气情况等各种常用界面&#xff0c;您可以将其用于旅游酒店类的APP应用…

华为云Flexus+DeepSeek征文 | 基于华为云ModelArts Studio搭建PandaWiki知识库问答系统

华为云FlexusDeepSeek征文 | 基于华为云ModelArts Studio搭建PandaWiki知识库问答系统 引言一、ModelArts Studio平台介绍华为云ModelArts Studio简介ModelArts Studio主要特点 二、PandaWiki介绍PandaWiki 简介主要特点 三、安装PandaWiki应用一键部署方式访问PandaWiki系统 四…

Python应用八股文

大家好!在 Python 学习的道路上&#xff0c;掌握一些基础知识要点至关重要&#xff0c;这些要点常被称为“Python 八股”。以下是对它们的简易总结&#xff0c;帮助你快速回顾和巩固 Python 的核心概念。 一、数据结构 列表&#xff08;List&#xff09;&#xff1a;有序可变序…

在 CentOS中安装Docker并安装青龙脚本——笔记

安装依赖 sudo yum install -y yum-utils device-mapper-persistent-data lvm2添加 Docker 官方 GPG 密钥 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo安装 Docker 引擎 sudo yum install -y docker-ce docker-ce-cli con…