责任链设计模式

责任链模式(ChainOfResponsibility)

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

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

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

现实场景

  • 简单的生产线

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

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

java 复制代码
// 定义一个处理请求的接口
interface Handler {
    void setNextHandler(Handler handler);
    void handleRequest(Request request);
}

// 具体的处理器类1
class ConcreteHandler1 implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler handler) {
        nextHandler = handler;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType().equals("Type1")) {
            System.out.println("ConcreteHandler1处理了请求:" + request.getContent());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 具体的处理器类2
class ConcreteHandler2 implements Handler {
    private Handler nextHandler;

    @Override
    public void setNextHandler(Handler handler) {
        nextHandler = handler;
    }

    @Override
    public void handleRequest(Request request) {
        if (request.getType().equals("Type2")) {
            System.out.println("ConcreteHandler2处理了请求:" + request.getContent());
        } else if (nextHandler != null) {
            nextHandler.handleRequest(request);
        }
    }
}

// 请求类
class Request {
    private String type;
    private String content;

    public Request(String type, String content) {
        this.type = type;
        this.content = content;
    }

    public String getType() {
        return type;
    }

    public String getContent() {
        return content;
    }
}

// 客户端代码
public class Main {
    public static void main(String[] args) {
        Handler handler1 = new ConcreteHandler1();
        Handler handler2 = new ConcreteHandler2();
        
        handler1.setNextHandler(handler2);

        Request request1 = new Request("Type1", "Request Content 1");
        Request request2 = new Request("Type2", "Request Content 2");
        Request request3 = new Request("Type3", "Request Content 3");

        handler1.handleRequest(request1);
        handler1.handleRequest(request2);
        handler1.handleRequest(request3);
    }
}

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

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

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

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

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

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

相关推荐
思忖小下7 小时前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
liyinuo20179 小时前
嵌入式(单片机方向)面试题总结
嵌入式硬件·设计模式·面试·设计规范
aaasssdddd9611 小时前
C++的封装(十四):《设计模式》这本书
数据结构·c++·设计模式
T1an-111 小时前
设计模式之【观察者模式】
观察者模式·设计模式
思忖小下13 小时前
梳理你的思路(从OOP到架构设计)_设计模式Factory Method模式
设计模式·工厂方法模式·eit
霁月风14 小时前
设计模式——工厂方法模式
c++·设计模式·工厂方法模式
发飙的蜗牛'16 小时前
23种设计模式
android·java·设计模式
NorthCastle1 天前
设计模式-创建型模式-简单工厂模式详解
设计模式·简单工厂模式
越甲八千1 天前
重拾设计模式-外观模式和适配器模式的异同
设计模式·适配器模式·外观模式
越甲八千1 天前
重拾设计模式--适配器模式
设计模式·适配器模式