【职责链】设计模式:构建灵活的请求处理系统

2024-08-26 13:12

本文主要是介绍【职责链】设计模式:构建灵活的请求处理系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文将深入探讨职责链模式的工作原理、实现方式,并分析其在现代软件架构中的应用。

引言

在复杂的业务逻辑中,请求的传递和处理往往涉及多个处理对象。传统的处理方式可能会导致组件之间高度耦合,难以维护和扩展。
职责链模式通过将请求沿链传递,直到找到合适的处理者,有效解决了这一问题。

概述

职责链模式是一种行为设计模式,它允许多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
这种模式将对象组成一条链,并沿着这条链传递请求,直到有对象处理它为止。

核心概念

请求(Request):需要处理的任务或信息。
处理者(Handler):链中的节点,负责处理请求或转发请求。

工作原理

  1. 客户端创建请求并将其发送到链的头部;
  2. 链中的每个处理者决定是否能够处理该请求;
  3. 如果能够处理,执行相应操作;否则,将请求转发到链中的下一个处理者;
  4. 这个过程一直持续,直到请求被处理或到达链的末端。

代码实现

方式一

Handler是所有处理器类的抽象父类,handle()方法是抽象方法。
每个具体的处理器类HandlerAHandlerBhandle()代码结构类似,如果它能处理该请求,就不继续向下传递;如果不能处理,则交由后面的处理器来处理(即调用successor.handle())。
HandlerChain是处理器链,一个记录了链头、链尾的链表。

public abstract class Handler {protected Handler successor = null;public void setSuccessor(Handler successor) {this.successor = successor;}public final void handle() {boolean handled = doHandle();if (successor != null && !handled) {successor.handle();}}protected abstract boolean doHandle();
}public class HandlerA extends Handler {@Overrideprotected boolean doHandle() {boolean handled = false;//...return handled;}
}public class HandlerB extends Handler {@Overrideprotected boolean doHandle() {boolean handled = false;//...return handled;}
}public class HandlerChain {private Handler head = null;private Handler tail = null;public void addHandler(Handler handler) {handler.setSuccessor(null);if (head == null) {head = handler;tail = handler;return;}tail.setSuccessor(handler);tail = handler;}public void handle() {if (head != null) {head.handle();}}
}// 使用举例
public class Application {public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}
}

方式 2

HandlerChain类用数组来保存所有的处理器类,且在handler()函数中调用每个处理器类的handler()函数。

public interface IHandler {boolean handle();
}public class HandlerA implements IHandler {@Overridepublic boolean handle() {boolean handled = false;//...return handled;}
}public class HandlerB implements IHandler {@Overridepublic boolean handle() {boolean handled = false;//...return handled;}
}public class HandlerChain {private List<IHandler> handlers = new ArrayList<>();public void addHandler(IHandler handler) {this.handlers.add(handler);}public void handle() {for (IHandler handler : handlers) {boolean handled = handler.handle();if (handled) {break;}}}
}// 使用举例
public class Application {public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}
}

变体

实际上,职责链模式还有一种变体,那就是请求会被所有的处理器都处理一遍,不存在中途停止的情况。

链表实现
public abstract class Handler {protected Handler successor = null;public void setSuccessor(Handler successor) {this.successor = successor;}public final void handle() {doHandle();if (successor != null) {successor.handle();}}protected abstract void doHandle();
}public class HandlerA extends Handler {@Overrideprotected void doHandle() {//...}
}public class HandlerB extends Handler {@Overrideprotected void doHandle() {//...}
}public class HandlerChain {private Handler head = null;private Handler tail = null;public void addHandler(Handler handler) {handler.setSuccessor(null);if (head == null) {head = handler;tail = handler;return;}tail.setSuccessor(handler);tail = handler;}public void handle() {if (head != null) {head.handle();}}
}// 使用举例
public class Application {public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}
}
数组实现
public interface IHandler {void handle();
}public class HandlerA implements IHandler {@Overridepublic void handle() { //...}
}public class HandlerB implements IHandler {@Overridepublic boolean handle() {//...}
}public class HandlerChain {private List<IHandler> handlers = new ArrayList<>();public void addHandler(IHandler handler) {this.handlers.add(handler);}public void handle() {for (IHandler handler : handlers) {handler.handle();}}
}// 使用举例
public class Application {public static void main(String[] args) {HandlerChain chain = new HandlerChain();chain.addHandler(new HandlerA());chain.addHandler(new HandlerB());chain.handle();}
}

性能和设计考量

职责链模式提供了请求处理的灵活性和可扩展性,但也需要考虑以下方面:

  • 性能问题:如果链过长,请求的传递可能会引入延迟。
  • 未知终点:请求可能在链的末端仍未被处理,需要有默认的处理策略。

最佳实践

  • 确保每个处理者明确自己的职责范围;
  • 避免创建过长的职责链,以免影响性能;
  • 提供默认的处理者,以防请求未被处理。

总结

职责链模式是一种强大且灵活的设计模式,它通过解耦请求发送者和接收者,提高了系统的可扩展性和可维护性。理解其工作原理和实现方式,有助于我们在面对复杂的请求处理逻辑时,设计出更加优雅和高效的解决方案。
另外,职责链模式经常用来开发框架的过滤器拦截器,如Servlet FilterSpring Interceptor,关于底层代码分析,将在后面文章中单独讲解。

这篇关于【职责链】设计模式:构建灵活的请求处理系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108659

相关文章

一文详解Python中数据清洗与处理的常用方法

《一文详解Python中数据清洗与处理的常用方法》在数据处理与分析过程中,缺失值、重复值、异常值等问题是常见的挑战,本文总结了多种数据清洗与处理方法,文中的示例代码简洁易懂,有需要的小伙伴可以参考下... 目录缺失值处理重复值处理异常值处理数据类型转换文本清洗数据分组统计数据分箱数据标准化在数据处理与分析过

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Go语言使用Buffer实现高性能处理字节和字符

《Go语言使用Buffer实现高性能处理字节和字符》在Go中,bytes.Buffer是一个非常高效的类型,用于处理字节数据的读写操作,本文将详细介绍一下如何使用Buffer实现高性能处理字节和... 目录1. bytes.Buffer 的基本用法1.1. 创建和初始化 Buffer1.2. 使用 Writ

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr