责任链设计模式

责任链模式(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

相关推荐
晨米酱6 小时前
JavaScript 中"对象即函数"设计模式
前端·设计模式
数据智能老司机11 小时前
精通 Python 设计模式——分布式系统模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——并发与异步模式
python·设计模式·编程语言
数据智能老司机12 小时前
精通 Python 设计模式——测试模式
python·设计模式·架构
数据智能老司机12 小时前
精通 Python 设计模式——性能模式
python·设计模式·架构
使一颗心免于哀伤12 小时前
《设计模式之禅》笔记摘录 - 21.状态模式
笔记·设计模式
数据智能老司机1 天前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机1 天前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
烛阴1 天前
【TS 设计模式完全指南】懒加载、缓存与权限控制:代理模式在 TypeScript 中的三大妙用
javascript·设计模式·typescript
李广坤2 天前
工厂模式
设计模式