Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!

全文目录:

    • 开篇语
    • 前言
    • 一、责任链模式概述
      • 责任链模式的组成部分:
    • 二、责任链模式的核心优势
    • 三、使用责任链模式解耦复杂接口
      • 1. 定义 Handler 接口
      • 2. 实现具体的 Handler
      • 3. 创建订单对象
      • 4. 在 Spring Boot 中使用责任链模式
      • 5. 配置责任链
      • 6. 客户端调用
    • 四、责任链模式的动态编排
    • 五、总结
    • 文末

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  随着业务需求的不断增加,很多系统中的业务逻辑变得越来越复杂,特别是在涉及多个服务或者多个步骤的接口中,如何确保每个环节的灵活性、可扩展性以及可维护性,成为了开发中必须考虑的重要问题。在这种场景下,责任链模式(Chain of Responsibility Pattern)应运而生,它为我们提供了一种非常好的解决方案。

  在本文中,我们将介绍如何在 Spring Boot 项目中使用责任链模式来解耦复杂接口的逻辑,并且通过动态编排的方式提高系统的灵活性和可扩展性。

一、责任链模式概述

  责任链模式是一种行为型设计模式,旨在通过将请求沿着处理链传递来实现解耦。它允许多个对象有机会处理请求,从而避免请求发送者与接收者之间的耦合关系。每个处理者在处理请求时决定是否将请求传递给链中的下一个处理者,这种方式使得责任的分配更加灵活。

责任链模式的组成部分:

  1. Handler(处理者):定义一个接口,通常包含一个处理请求的方法和指向下一个处理者的引用。
  2. ConcreteHandler(具体处理者):实现处理请求的方法,并决定是否继续传递请求到链中的下一个处理者。
  3. Client(客户端):向链中的处理者发送请求。

二、责任链模式的核心优势

  1. 解耦:请求发送者不需要知道哪个对象会处理它,它只需要发出请求并交给链上的某个处理者,处理者的选择完全由责任链决定。
  2. 灵活性和可扩展性:可以轻松地增加、删除处理者,或者动态地改变处理链的顺序,增加了系统的灵活性和可维护性。
  3. 动态编排:责任链模式适用于有多个处理步骤且每个步骤可能根据不同条件进行执行的场景。通过将处理逻辑分散到不同的处理者中,用户可以根据业务需求动态调整处理链。

三、使用责任链模式解耦复杂接口

在实际业务中,常常会遇到这样的问题:一个接口的执行需要多个步骤,而每个步骤都有不同的处理逻辑。如果这些逻辑直接写在接口中,接口会变得非常复杂且难以维护。

例如,假设我们有一个订单处理的场景,其中订单需要经过多个环节的处理,如验证订单、计算订单金额、检查库存、处理支付等。如果把所有这些处理逻辑都放到一个方法中,代码会非常混乱,且扩展不方便。责任链模式可以将每个处理环节抽象为一个独立的处理者,并根据需要动态构建责任链。

1. 定义 Handler 接口

首先,我们需要定义一个处理者接口,所有的具体处理者都会实现这个接口:

public interface OrderHandler {void handle(Order order);void setNextHandler(OrderHandler nextHandler);
}
  • handle(Order order):处理当前请求的方法,订单对象作为请求传递。
  • setNextHandler(OrderHandler nextHandler):设置下一个处理者。

2. 实现具体的 Handler

接下来,我们实现多个具体的处理者。例如,OrderValidationHandler 用于订单验证,OrderCalculationHandler 用于计算订单金额,OrderPaymentHandler 用于支付处理等:

public class OrderValidationHandler implements OrderHandler {private OrderHandler nextHandler;@Overridepublic void handle(Order order) {System.out.println("Validating order...");// 执行订单验证逻辑if (order.isValid()) {if (nextHandler != null) {nextHandler.handle(order);}} else {System.out.println("Order validation failed.");}}@Overridepublic void setNextHandler(OrderHandler nextHandler) {this.nextHandler = nextHandler;}
}public class OrderCalculationHandler implements OrderHandler {private OrderHandler nextHandler;@Overridepublic void handle(Order order) {System.out.println("Calculating order amount...");// 执行订单金额计算逻辑order.setAmount(order.getAmount() * 1.1); // 假设给订单加上10%的税if (nextHandler != null) {nextHandler.handle(order);}}@Overridepublic void setNextHandler(OrderHandler nextHandler) {this.nextHandler = nextHandler;}
}public class OrderPaymentHandler implements OrderHandler {private OrderHandler nextHandler;@Overridepublic void handle(Order order) {System.out.println("Processing payment...");// 执行支付逻辑if (order.getAmount() > 0) {System.out.println("Payment processed successfully!");if (nextHandler != null) {nextHandler.handle(order);}} else {System.out.println("Payment failed due to invalid amount.");}}@Overridepublic void setNextHandler(OrderHandler nextHandler) {this.nextHandler = nextHandler;}
}

3. 创建订单对象

Order 类包含订单的基本信息,例如金额、验证状态等:

public class Order {private double amount;private boolean valid;public Order(double amount, boolean valid) {this.amount = amount;this.valid = valid;}public double getAmount() {return amount;}public void setAmount(double amount) {this.amount = amount;}public boolean isValid() {return valid;}public void setValid(boolean valid) {this.valid = valid;}
}

4. 在 Spring Boot 中使用责任链模式

通过 Spring Boot,我们可以将这些责任链的处理者作为 Spring 的 Bean 注入,从而灵活地在服务中动态创建和修改责任链的顺序。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class OrderService {private final OrderHandler firstHandler;@Autowiredpublic OrderService(OrderHandler firstHandler) {this.firstHandler = firstHandler;}public void processOrder(Order order) {firstHandler.handle(order);}
}

5. 配置责任链

在 Spring Boot 中,我们可以通过配置类来定义责任链的顺序:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class OrderConfig {@Beanpublic OrderHandler orderHandler() {OrderValidationHandler validationHandler = new OrderValidationHandler();OrderCalculationHandler calculationHandler = new OrderCalculationHandler();OrderPaymentHandler paymentHandler = new OrderPaymentHandler();validationHandler.setNextHandler(calculationHandler);calculationHandler.setNextHandler(paymentHandler);return validationHandler;}
}

6. 客户端调用

客户端可以通过调用 OrderService 来执行订单处理的责任链:

@SpringBootApplication
public class OrderApplication {public static void main(String[] args) {ApplicationContext context = SpringApplication.run(OrderApplication.class, args);OrderService orderService = context.getBean(OrderService.class);Order order = new Order(100, true); // 有效订单orderService.processOrder(order);  // 处理订单}
}

四、责任链模式的动态编排

  责任链模式最大的优势之一就是动态编排。在业务流程变化或者新增业务处理逻辑时,我们可以在运行时灵活地调整处理者的顺序,甚至添加新的处理环节,而无需大幅修改现有的代码结构。

例如,在实际业务中,如果我们要在订单处理中加入新的环节(如 OrderNotificationHandler),只需要简单地创建一个新的处理者,并将其加入到责任链中。

五、总结

  责任链模式在 Spring Boot 项目中的应用非常灵活,它通过解耦复杂接口的逻辑、动态编排处理顺序,为我们提供了一种可扩展、易维护的解决方案。通过将业务处理流程分解为多个独立的处理者,我们可以方便地管理每个环节的业务逻辑,并在必要时灵活调整和扩展业务流程。

  使用责任链模式,我们不仅能够优化系统的结构,还能够提升系统的灵活性和可维护性,特别是当面对复杂的业务流程时,责任链模式尤为有效。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

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

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

相关文章

COMSOL仿真遇到的两个小问题

最近跑热仿真的时候跑出了两个问题,上网查发现也没什么解决方式,最后自己误打误撞的摸索着解决了,在这里分享一下。 问题一 我当时一准备跑仿真就弹出了这个东西,但在此之前从未遇到 然后我试着在它说的路径中建立recoveries文件…

如何在英文学术写作中正确使用标点符号?

标点符号看似微不足道,但它们是书面语言的无名英雄。就像熟练的指挥家指挥管弦乐队一样,标点符号可以确保您的写作流畅、传达正确的含义并引起读者的共鸣。正如放错位置的音符会在音乐中造成不和谐一样,放错位置的逗号或缺少分号也会使您的写…

【深度学习与大模型基础】第10章-期望、方差和协方差

一、期望 ——————————————————————————————————————————— 1. 期望是什么? 期望(Expectation)可以理解为“长期的平均值”。比如: 掷骰子:一个6面骰子的点数是1~6&#x…

JAVA虚拟机(JVM)学习

入门 什么是JVM JVM:Java Virtual Machine,Java虚拟机。 JVM是JRE(Java Runtime Environment)的一部分,安装了JRE就相当于安装了JVM,就可以运行Java程序了。JVM的作用:加载并执行Java字节码(.class&#…

【数据结构与算法】——堆(补充)

前言 上一篇文章讲解了堆的概念和堆排序,本文是对堆的内容补充 主要包括:堆排序的时间复杂度、TOP 这里写目录标题 前言正文堆排序的时间复杂度TOP-K 正文 堆排序的时间复杂度 前文提到,利用堆的思想完成的堆排序的代码如下(包…

什么是柜台债

柜台债(柜台债券业务)是指通过银行等金融机构的营业网点或电子渠道,为投资者提供债券买卖、托管、结算等服务的业务模式。它允许个人、企业及机构投资者直接参与银行间债券市场的交易,打破了以往仅限机构参与的壁垒。以下是综合多…

【Android读书笔记】读书笔记记录

文章目录 一. Android开发艺术探索1. Activity的生命周期和启动模式1.1 生命周期全面分析 一. Android开发艺术探索 1. Activity的生命周期和启动模式 1.1 生命周期全面分析 onPause和onStop onPause后会快速调用onStop,极端条件下直接调用onResume 当用户打开新…

Java对象内存结构详解

Java对象内存结构详解 Java对象在JVM内存中的存储结构可以分为三个部分:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。以下是64位JVM(开启压缩指针)下…

【TI MSPM0】Printf重定向学习

一、新建工程 通过XDS110与电脑进行通信。 选择这两个引脚 需要添加这两个头文件 在程序中添加这三个函数即可对printf进行重定向 二、封装函数 另一种方法 封装一个函数,定义一个数组

深度强化学习基础 0:通用学习方法

过去自己学习深度强化学习的痛点: 只能看到各种术语、数学公式勉强看懂,没有建立清晰且准确关联 多变量交互关系浮于表面,有时候连环境、代理控制的变量都混淆 模型种类繁多,概念繁杂难整合、对比或复用,无框架分析所…

asm汇编源代码之-字库转换程序

将标准的16x16点阵汉字库(下载16x16汉字库)转换成适合VGA文本模式下显示的点阵汉字库 本程序需要调用file.asm中的子程序,所以连接时需要把file连接进来,如下 C:\> tlink chghzk file 调用参数描述如下 C:\> chghzk ; 无调用参数,转换标准库文件(SRC16.FNT)为适合VGA…

uniapp转换markdown

效果 AI智能体 微信小程序 流式 1.安装Node.js 参考:2024最新版Node.js下载安装及环境配置教程(非常详细)_node.js 安装-CSDN博客 2.需要克隆项目到本地或直接到项目地址下载压缩包。 参考:uniapp中解析markdown支持网页和小程序_uniapp ma…

用java代码如何存取数据库的blob字段

一.业务 在业务中我们被要求将文件或图片等转成 byte[] 或 InputStream存到数据库的Blob类型的字段中. 二.Blob类型介绍 在 MySQL 中,Blob 数据类型用于存储二进制数据。MySQL 提供了四种不同的 Blob 类型: TINYBLOB: 最大存储长度为 255 个字节。BL…

qemu(2) -- 定制开发板

1. 前言 qemu支持自定义开发板,本文就记录一下折腾的过程。基于qemu-10.0.0-rc3添加x210vb3s开发板。 2. 添加板卡文件 网上参考了一些文章,有些文章使用的版本和我的不一样,折腾起来费了点时间,最后发现还是直接参考qemu中已有…

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM)

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM) 问题模板解题思路1. 导入必要的库2. 加载数据3. 划分训练集和测试集4. 数据预处理5. 定义算法及其参数6. 存储算法和对应指标7. 训练模型并计算指标8. 找…

CPU(中央处理器)

一、CPU的定义与核心作用 CPU 是计算机的核心部件,负责 解释并执行指令、协调各硬件资源 以及 完成数据处理,其性能直接影响计算机的整体效率。 核心功能: 从内存中读取指令并译码。执行算术逻辑运算。控制数据在寄存器、内存和I/O设备间的…

上层 Makefile 控制下层 Makefile 的方法

在复杂的项目中,通常会将项目划分为多个模块或子项目,每个模块都有自己的 Makefile。上层 Makefile 的作用是协调和控制这些下层 Makefile 的构建过程。下面是几种常见的示例,实现上层 Makefile 对下层 Makefile 的控制。 直接调用&#xff1…

prompts提示词经典模板

prompts.py 中的提示词模板详解 文件中定义了两个核心提示词模板:REASON_PROMPT 和 RELEVANT_EXTRACTION_PROMPT。这两个模板在 DeepResearcher 的推理过程中扮演着关键角色。下面我将详细解析这两个模板的结构和功能。 REASON_PROMPT 详解 REASON_PROMPT 是用于指…

使用python获取电脑硬盘信息

import psutil# 获取硬盘信息 disk_partitions psutil.disk_partitions() print(disk_partitions) for partition in disk_partitions:print(f"设备: {partition.device}")print(f"挂载点: {partition.mountpoint}")print(f"文件系统类型: {partitio…

HarmonyOS-ArkUI V2装饰器: @Provider和@Consumer装饰器:跨组件层级双向同步

作用 我们在之前学习的那些控件中,各有特点,也各有缺陷,至今没有痛痛快快的出现过真正能跨组件的双向绑定的装饰器。 比如 @Local装饰器,不能跨组件@Param装饰器呢,能跨组件传递,但是仅仅就是下一层组件接收参数。另外,它是单向传递,不可被重新赋值。如果您非要改值则…