责任链设计模式

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

相关推荐
哪 吒3 小时前
最简单的设计模式,抽象工厂模式,是否属于过度设计?
设计模式·抽象工厂模式
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
转世成为计算机大神6 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
小乖兽技术7 小时前
23种设计模式速记法
设计模式
小白不太白9509 小时前
设计模式之 外观模式
microsoft·设计模式·外观模式
小白不太白9509 小时前
设计模式之 原型模式
设计模式·原型模式
澄澈i9 小时前
设计模式学习[8]---原型模式
学习·设计模式·原型模式
小白不太白95016 小时前
设计模式之建造者模式
java·设计模式·建造者模式
菜菜-plus18 小时前
java 设计模式 模板方法模式
java·设计模式·模板方法模式
萨达大18 小时前
23种设计模式-模板方法(Template Method)设计模式
java·c++·设计模式·软考·模板方法模式·软件设计师·行为型设计模式