51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

设计模式精讲:责任链模式,如何将责任串成链?

嗨,你好呀,我是猿java

责任链设计模式是一种行为型设计模式,它允许多个对象有机会处理请求,从而避免请求的发送者和接收者之间的耦合。将这些对象连成一条链,并沿着这条链传递请求,直到有对象处理它为止。这篇文章,我们将详细地分析责任链设计模式,了解它的优缺点,以及在实际应用中的场景。

  1. 什么是责任链模式? {#1-什么是责任链模式?} ===========================

责任链设计模式(Chain of Responsibility Pattern)是一种行为型设计模式 ,允许一个对象将请求沿着一条处理者链传递。这种模式的核心思想是,请求的发送者不知道最终会由哪个对象来处理请求

这种模式在需要多个对象依次处理请求的情况下非常常见,例如每个对象可以选择处理该请求,或者如果无法处理,则将请求传递给链中的下一个对象。

责任链模式主要由以下几个部分组成:

  • 抽象处理者(Handler) :定义一个处理请求的接口,并且可以定义一个后继链接。
  • 具体处理者(ConcreteHandler) :实现抽象处理者的接口,具体处理请求的对象。
  • 客户类(Client) :负责创建处理链,并向链中的处理者提交请求。

img

  1. 责任链模式的特性 {#2-责任链模式的特性} =========================

责任链设计模式的主要特点包含以下几点:

  1. 松耦合: 请求发送者不需要知道具体哪个对象会处理该请求。处理者之间也没有强依赖关系。

  2. 动态链:处理链可以在程序运行时动态改变,例如添加或删除链中的处理者。

  3. 单一职责原则: 每个处理者的职责非常明确:要么处理请求,要么将请求传递给下一个处理者。

  4. 顺序处理:请求按照链的顺序依次通过,确保处理逻辑的一致性。

  5. 回退机制:如果所有的处理者都无法处理请求,可以提供一个默认的回退选项,确保请求得到妥善处理。

  6. 如何实现责任链模式? {#3-如何实现责任链模式?} =============================

实现责任链设计模式,主要包含以下步骤:

  1. 定义处理者接口:创建一个接口,定义设置下一个处理者和处理请求的方法。

  2. 实现具体处理者:在多个类中实现上述接口,根据自身职责决定是处理请求还是将其传递给下一处理者。

  3. 设置责任链:创建各处理者的实例,并将它们按照顺序链接起来。

  4. 提交请求:使用责任链的第一个处理者发送请求,依次经过链中的其他处理者,直到某个处理者完成请求或链结束。

为了更好地理解责任链模式,下面通过一个简单的示例来演示责任链模式的实现:

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | // 1. 定义处理者接口: 抽象处理者 abstract class Handler { protected Handler successor; public void setSuccessor(Handler successor) { this.successor = successor; } public abstract void handleRequest(int request); } // 实现具体处理者, 包含处理者1,处理者2,处理者3 // 具体处理者1 class ConcreteHandler1 extends Handler { public void handleRequest(int request) { if (request < 10) { System.out.println("ConcreteHandler1 handled request " + request); } else if (successor != null) { successor.handleRequest(request); } } } // 具体处理者2 class ConcreteHandler2 extends Handler { public void handleRequest(int request) { if (request >= 10 && request < 20) { System.out.println("ConcreteHandler2 handled request " + request); } else if (successor != null) { successor.handleRequest(request); } } } // 具体处理者3 class ConcreteHandler3 extends Handler { public void handleRequest(int request) { if (request >= 20) { System.out.println("ConcreteHandler3 handled request " + request); } else if (successor != null) { successor.handleRequest(request); } } } // 客户端 public class Client { public static void main(String[] args) { // 创建处理者 Handler handler1 = new ConcreteHandler1(); Handler handler2 = new ConcreteHandler2(); Handler handler3 = new ConcreteHandler3(); // 设置责任链 handler1.setSuccessor(handler2); handler2.setSuccessor(handler3); // 提交请求 int[] requests = {2, 14, 22, 18, 3, 27}; for (int request : requests) { handler1.handleRequest(request); } } } |

通过上述示例,我们可以看到责任链模式的实现,它可以实现一个请求的处理,并将请求传递给下一个处理者,直到某个处理者完成请求或链结束。

  1. 使用责任链模式的框架 {#4-使用责任链模式的框架} =============================

责任链设计模式在许多 Java框架中都有应用,特别是在处理请求和响应的场景中,以下列举了一些常用的 Java框架和工具:

  1. Servlet Filter: Java Servlet API中的过滤器(Filter)机制就是责任链模式的一个典型应用。多个过滤器可以串联在一起,形成一个责任链,每个过滤器都可以对请求和响应进行预处理或后处理。

  2. Spring Security: Spring Security使用责任链模式来处理安全性操作。安全过滤器链(Security Filter Chain)允许多个过滤器对请求进行安全性检查,如身份验证和授权。

  3. Apache Commons Chain: Apache Commons Chain是一个专门实现责任链模式的库,用于创建和管理责任链。它提供了一种灵活的方式来定义和执行命令链。

  4. Netty:Netty是一个异步事件驱动的网络应用框架,常用于高性能协议服务器和客户端。Netty使用责任链模式来处理网络事件,通过管道(Pipeline)和处理器(Handler)来实现事件的传递和处理。

  5. Apache Struts 2:Struts 2框架利用拦截器(Interceptor)来实现责任链模式。拦截器在请求到达Action之前或响应返回客户端之前对其进行处理。

  6. Spring WebFlux:Spring WebFlux中的过滤器和处理器链也是责任链模式的一个实现。它允许开发者定义一系列的处理器来处理Web请求。

  7. Mule ESB: Mule ESB是一个轻量级的企业服务总线(ESB),它使用责任链模式来处理消息流。每个组件可以作为责任链中的一个节点,对消息进行处理。

5 责任链模式的优缺点 {#5-责任链模式的优缺点}

5.1 优点 {#5-1-优点}

  1. 降低耦合性:发送者和接收者不需要直接交互,减少了对象之间的依赖。
  2. 灵活扩展:添加或移除处理者不影响客户端代码。
  3. 职责单一:每个处理者专注于自身的职责范围。
  4. 动态可调:可以在运行时改变处理链的结构。

5.2 缺点 {#5-2-缺点}

  1. 可能未处理:如果实现不正确,某些请求可能不会被处理。

  2. 性能开销:请求经过多个处理者可能造成性能损失。

  3. 调试复杂:链条较长时,难以跟踪请求的流向和处理情况。

  4. 维护困难:链动态修改时可能难以管理。

  5. 总结 {#6-总结} =============

这篇文章我们详细地分析了责任链设计模式,并通过代码示例实现了该模式的应用。责任链模式是一种强大的工具,用于构建灵活且可扩展的请求处理结构,它可以显著降低代码耦合性,提高系统的灵活性。从整体上看,责任链模式是一种比较容易理解的设计模式。

  1. 交流学习 {#7-交流学习} =================

最后,把猿哥的座右铭送给你:投资自己才是最大的财富。 如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注公众号:猿java,持续输出硬核文章。

赞(0)
未经允许不得转载:工具盒子 » 设计模式精讲:责任链模式,如何将责任串成链?