IT评测·应用市场-qidao123.com

标题: 重学设计模式-责任链模式 [打印本页]

作者: 前进之路    时间: 2025-1-2 04:27
标题: 重学设计模式-责任链模式
责任链模式(Chain of Responsibility Pattern)是一种举动设计模式,它通过将请求沿着链转达,使多个对象都有机会处理该请求,从而避免了请求的发送者与接收者之间的耦合关系。本文将具体介绍责任链模式的定义、优缺点、应用场景,并通过Java代码展示其实现过程。
一、责任链模式的定义

责任链模式又称为职责链模式,其核心思想是将所有请求的处理者通过前一对象记着其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链转达,直到有对象处理它为止。在这种模式下,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的转达过程,因此责任链将请求的发送者和请求的处理者解耦了。
责任链模式属于对象举动型模式,它主要由以下几个角色构成:
抽象处理者(Handler):定义一个处理请求的接口,包罗抽象处理方法和一个后继毗连。
具体处理者(Concrete Handler):实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类(Client):创建处理链,并向链头的具体处理者对象提交请求,无需关心处理细节和请求的转达过程。

二、责任链模式的优缺点

优点
低落了对象之间的耦合度:该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
增强了系统的可扩展性:可以根据需要增加新的请求处理类,满意开闭原则。
增强了给对象指派职责的灵活性:当工作流程发生变化时,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
责任链简化了对象之间的毗连:每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了利用浩繁的 if 或者 if-else 语句。
责任分担:每个类只需要处理自己该处理的工作,不该处理的转达给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
缺点
不能保证每个请求肯定被处理:由于一个请求没有明确的接收者,所以不能保证它肯定会被处理,该请求可能一直传到链的末端都得不随处理。
对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到肯定影响:遍历多个处理者会影响性能,特殊是在一些递归调用中。
责任链创建的公道性要靠客户端来保证,增加了客户端的复杂性:可能会由于责任链的错误设置而导致系统出错,如可能会造成循环调用。
三、责任链模式的应用场景
先介绍一下作者实习时用到的,抽奖需要有规则配置,抽奖前和抽奖后都需要进行规则判断,抽奖中规则采用决策树与本文无关不多做赘述,抽奖前起首要判断是否已登录,再判断是否为黑名单,再判断抽奖次数是否到达抽该奖品的要求,等等一系列判断,只要有一个判断失败就返回,这种情况用责任链模式就非常方便,且对后面的增删查改更加友爱
责任链模式在多个场景中都有广泛应用,包括但不限于:
公司事件等级制度:一切关于工程的事件必须根据事件紧张等级匹配相应职位的人员处理,如果事件紧张等级凌驾该职位设定的处理范围就需要向上级陈诉,交由上级处理。
Java过滤器:如Netty中的Pipeline和ChannelHandler,Spring Security,Spring AOP,Dubbo Filter过滤器链等。
ERP系统流程审批:如总经理、人事经理、项目经理的审批流程。
权限控制:在网关作为微服务步调的入口,拦截客户端所有的请求实现权限控制,如先判断Api接口限流、黑名单、用户会话、参数过滤等。
四、Java实现责任链模式

下面是一个具体的Java代码示例,展示了怎样实现责任链模式。
java代码示例
  1. public class Request {
  2.     private String message;
  3.     public Request(String message) {
  4.         this.message = message;
  5.     }
  6.     public String getMessage() {
  7.         return message;
  8.     }
  9. }
复制代码
java代码示例
  1. public interface Handler {
  2.     void setNext(Handler handler); // 设置下一个处理者
  3.     void handle(Request request); // 处理请求的方法
  4. }
复制代码
java代码示例
  1. // 处理者类 A
  2. public class ConcreteHandlerA implements Handler {
  3.     private Handler nextHandler;
  4.     @Override
  5.     public void setNext(Handler handler) {
  6.         this.nextHandler = handler;
  7.     }
  8.     @Override
  9.     public void handle(Request request) {
  10.         if (request.getMessage().equals("A")) {
  11.             System.out.println("Handler A processed request: " + request.getMessage());
  12.         } else if (nextHandler != null) {
  13.             nextHandler.handle(request);
  14.         }
  15.     }
  16. }
  17. // 处理者类 B
  18. public class ConcreteHandlerB implements Handler {
  19.     private Handler nextHandler;
  20.     @Override
  21.     public void setNext(Handler handler) {
  22.         this.nextHandler = handler;
  23.     }
  24.     @Override
  25.     public void handle(Request request) {
  26.         if (request.getMessage().equals("B")) {
  27.             System.out.println("Handler B processed request: " + request.getMessage());
  28.         } else if (nextHandler != null) {
  29.             nextHandler.handle(request);
  30.         }
  31.     }
  32. }
  33. // 处理者类 C
  34. public class ConcreteHandlerC implements Handler {
  35.     private Handler nextHandler;
  36.     @Override
  37.     public void setNext(Handler handler) {
  38.         this.nextHandler = handler;
  39.     }
  40.     @Override
  41.     public void handle(Request request) {
  42.         if (request.getMessage().equals("C")) {
  43.             System.out.println("Handler C processed request: " + request.getMessage());
  44.         } else if (nextHandler != null) {
  45.             nextHandler.handle(request);
  46.         }
  47.     }
  48. }
  49. 4. 组装责任链并测试
  50. 最后,我们需要创建一个类来组合所有处理器,形成一个责任链,并通过调用handle方法测试不同的请求。
  51. java
  52. public class ChainOfResponsibility {
  53.     public static void main(String[] args) {
  54.         Handler handlerA = new ConcreteHandlerA();
  55.         Handler handlerB = new ConcreteHandlerB();
  56.         Handler handlerC = new ConcreteHandlerC();
  57.         // 设置责任链
  58.         handlerA.setNext(handlerB);
  59.         handlerB.setNext(handlerC);
  60.         // 测试请求
  61.         Request requestA = new Request("A");
  62.         Request requestB = new Request("B");
  63.         Request requestC = new Request("C");
  64.         Request requestD = new Request("D");
  65.         // 处理请求
  66.         handlerA.handle(requestA); // Handler A processed request: A
  67.         handlerA.handle(requestB); // Handler B processed request: B
  68.         handlerA.handle(requestC); // Handler C processed request: C
  69.         handlerA.handle(requestD); // 无任何处理
  70.     }
  71. }
复制代码
运行上述代码,你将看到每个请求按照设置的责任链被处理。对应于请求"A"、"B"和"C"的处理结果将被打印出来,而请求"D"则未被处理。
五、责任链模式的变种与扩展

除了上述基本实现外,责任链模式还可以进行变种和扩展,以适应差异的应用场景。
java代码示例
  1. // 带有返回值的请求处理接口
  2. public interface Handler<T> {
  3.     void setNext(Handler<T> handler);
  4.     T handle(Request request);
  5. }
  6. // 具体的处理者类A,带有返回值
  7. public class ConcreteHandlerA implements Handler<String> {
  8.     private Handler<String> nextHandler;
  9.     @Override
  10.     public void setNext(Handler<String> handler) {
  11.         this.nextHandler = handler;
  12.     }
  13.     @Override
  14.     public String handle(Request request) {
  15.         if (request.getMessage().equals("A")) {
  16.             return "Handler A processed request: " + request.getMessage();
  17.         } else if (nextHandler != null) {
  18.             return nextHandler.handle(request);
  19.         }
  20.         return null;
  21.     }
  22. }
  23. // 具体的处理者类B,带有返回值
  24. public class ConcreteHandlerB implements Handler<String> {
  25.     private Handler<String> nextHandler;
  26.     @Override
  27.     public void setNext(Handler<String> handler) {
  28.         this.nextHandler = handler;
  29.     }
  30.     @Override
  31.     public String handle(Request request) {
  32.         if (request.getMessage().equals("B")) {
  33.             return "Handler B processed request: " + request.getMessage();
  34.         } else if (nextHandler != null) {
  35.             return nextHandler.handle(request);
  36.         }
  37.         return null;
  38.     }
  39. }
  40. // 具体的处理者类C,带有返回值
  41. public class ConcreteHandlerC implements Handler<String> {
  42.     private Handler<String> nextHandler;
  43.     @Override
  44.     public void setNext(Handler<String> handler) {
  45.         this.nextHandler = handler;
  46.     }
  47.     @Override
  48.     public String handle(Request request) {
  49.         if (request.getMessage().equals("C")) {
  50.             return "Handler C processed request: " + request.getMessage();
  51.         } else if (nextHandler != null) {
  52.             return nextHandler.handle(request);
  53.         }
  54.         return null;
  55.     }
  56. }
  57. // 请求类,包含需要被处理的信息
  58. public class Request {
  59.     private String message;
  60.     public Request(String message) {
  61.         this.message = message;
  62.     }
  63.     public String getMessage() {
  64.         return message;
  65.     }
  66.     public void setMessage(String message) {
  67.         this.message = message;
  68.     }
  69. }
  70. // 客户端代码,用于测试责任链模式
  71. public class Client {
  72.     public static void main(String[] args) {
  73.         // 创建处理者实例
  74.         Handler<String> handlerA = new ConcreteHandlerA();
  75.         Handler<String> handlerB = new ConcreteHandlerB();
  76.         Handler<String> handlerC = new ConcreteHandlerC();
  77.         // 设置责任链
  78.         handlerA.setNext(handlerB);
  79.         handlerB.setNext(handlerC);
  80.         // 创建请求
  81.         Request request1 = new Request("A");
  82.         Request request2 = new Request("B");
  83.         Request request3 = new Request("C");
  84.         Request request4 = new Request("D"); // 未知请求,测试链的末尾处理
  85.         // 处理请求并打印结果
  86.         System.out.println(handlerA.handle(request1)); // 输出: Handler A processed request: A
  87.         System.out.println(handlerA.handle(request2)); // 输出: Handler B processed request: B
  88.         System.out.println(handlerA.handle(request3)); // 输出: Handler C processed request: C
  89.         System.out.println(handlerA.handle(request4)); // 输出: null(没有处理者处理这个请求)
  90.     }
  91. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4