• 责任链设计模式


    责任链模式(ChainOfResponsibility)

    亦称:职责链模式、命令链、CoR、Chain of Command、Chain of Responsibility

    责任链是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。

    责任链是由很多责任节点串联起来的一条任务链条,其中每一个责任节点都是一个业务处理环节。责任链模式(Chain ofResponsibility)允许业务请求者将责任链视为一个整体并对其发起请求,而不必关心链条内部具体的业务逻辑与流程走向,也就是说,请求者不必关心具体是哪个节点起了作用,总之业务最终能得到相应的处理。在软件系统中,当一个业务需要经历一系列业务对象去处理时,我们可以把这些业务对象串联起来成为一条业务责任链,请求者可以直接通过访问业务责任链来完成业务的处理,最终实现请求者与响应者的解耦。

    现实场景

    • 简单的生产线

    倘若一个系统中有一系列零散的功能节点,它们都负责处理相关的业务,但处理方式又各不相同。这时客户面对这么一大堆功能节点可能无从下手,根本不知道选择哪个功能节点去提交请求,返回的结果也许只是个半成品,还得再次提交给下一个功能节点,处理过程相当烦琐。虽然从某种角度看,每个功能节点均承担各自的义务,分工明确、各司其职,但从外部来看则显得毫无组织,团队犹如一盘散沙。所以为了更高效、更完整地解决客户的问题,各节点一定要发扬团队精神,利用责任链模式组织起来,形成一个有序、有效的业务处理集群,为客户提供更方便、更快捷的服务。

    以最简单的责任链举例,汽车生产线的制造流程就使用了这种模式。首先我们进行劳动分工,将汽车零件的安装工作拆分并分配给各安装节点,责任明确划分;然后架构生产线,将安装节点组织起来,首尾相接,规划操作流程;最终,通过生产线的传递,汽车便从零件到成品得以量产,生产效率大大提升。

    1. // 定义一个处理请求的接口
    2. interface Handler {
    3. void setNextHandler(Handler handler);
    4. void handleRequest(Request request);
    5. }
    6. // 具体的处理器类1
    7. class ConcreteHandler1 implements Handler {
    8. private Handler nextHandler;
    9. @Override
    10. public void setNextHandler(Handler handler) {
    11. nextHandler = handler;
    12. }
    13. @Override
    14. public void handleRequest(Request request) {
    15. if (request.getType().equals("Type1")) {
    16. System.out.println("ConcreteHandler1处理了请求:" + request.getContent());
    17. } else if (nextHandler != null) {
    18. nextHandler.handleRequest(request);
    19. }
    20. }
    21. }
    22. // 具体的处理器类2
    23. class ConcreteHandler2 implements Handler {
    24. private Handler nextHandler;
    25. @Override
    26. public void setNextHandler(Handler handler) {
    27. nextHandler = handler;
    28. }
    29. @Override
    30. public void handleRequest(Request request) {
    31. if (request.getType().equals("Type2")) {
    32. System.out.println("ConcreteHandler2处理了请求:" + request.getContent());
    33. } else if (nextHandler != null) {
    34. nextHandler.handleRequest(request);
    35. }
    36. }
    37. }
    38. // 请求类
    39. class Request {
    40. private String type;
    41. private String content;
    42. public Request(String type, String content) {
    43. this.type = type;
    44. this.content = content;
    45. }
    46. public String getType() {
    47. return type;
    48. }
    49. public String getContent() {
    50. return content;
    51. }
    52. }
    53. // 客户端代码
    54. public class Main {
    55. public static void main(String[] args) {
    56. Handler handler1 = new ConcreteHandler1();
    57. Handler handler2 = new ConcreteHandler2();
    58. handler1.setNextHandler(handler2);
    59. Request request1 = new Request("Type1", "Request Content 1");
    60. Request request2 = new Request("Type2", "Request Content 2");
    61. Request request3 = new Request("Type3", "Request Content 3");
    62. handler1.handleRequest(request1);
    63. handler1.handleRequest(request2);
    64. handler1.handleRequest(request3);
    65. }
    66. }

    在上面的例子中,我们定义了一个Handler接口,该接口具有设置下一个处理器和处理请求的方法。然后我们创建了两个具体的处理器类ConcreteHandler1ConcreteHandler2,分别处理请求的类型Type1Type2。如果请求的类型不是当前处理器所能处理的,就将请求传递给下一个处理器处理。

    最后,在客户端代码中,我们创建了两个处理器实例,并通过setNextHandler方法将它们串联起来形成责任链。然后我们创建了三个不同类型的请求,并通过调用handleRequest方法将其交给责任链进行处理。

    在执行的过程中,当请求的类型匹配到对应的处理器时,该处理器就会处理该请求,否则会将该请求传递给下一个处理器。这样,请求就会依次经过责任链中的处理器进行处理。

            例如在mybatius中的缓存设计使用了装饰器+责任链,通过log缓存、序列化缓存、同步缓存等一系列缓存支持缓存的多种功能,优缺点是,

    • 你可以控制请求处理的顺序。
    • 单一职责原则。你可对发起操作和执行操作的类进行解耦。
    • 开闭原则。你可以在不更改现有代码的情况下在程序中新增处理者。
    • 缺点:部分请求可能未被处理。
    • 缺点:debug可能会比较困难。

            在sql解析中也有用到责任链,mybatius将sql解析成sqlNode,然后通过责任链,调用每个sqlNode的解析方式(解析类)。将所有解析完成的sql拼接成统一的sql,再利用jdbc,创建connection,利用 preparedstatement将参数设置到sql中,获取resultset

  • 相关阅读:
    图解Kubernetes的Pod核心资源-来白嫖啊
    STM32入门笔记14_RTC实时时钟
    .NetCore中使用分布式事务DTM的二阶段消息
    【面试刷题】——C++的特点简单说明
    Git多人开发解决冲突案例
    五、接口测试工具:Postman
    new`是如何创建对象实例的?
    创建型设计模式
    halcon入门学习-ball.hdev
    Nacos下载与安装详解
  • 原文地址:https://blog.csdn.net/qq_27413937/article/details/133657758