设计模式详解(十八)——责任链模式

责任链模式简介

责任链模式定义

责任链模式是一种行为设计模式,它的本质在于解耦请求与处理,让请求在处理链中能进行传递与处理。在责任链模式中,多个对象依次处理同一个请求,每个对象都包含对下一个对象的引用。当一个对象处理完请求后,会将请求传递给下一个对象,直到所有对象都处理完毕。这样可以动态地决定请求的处理顺序,并且可以灵活地添加、移除或修改处理对象,而不影响客户端代码。责任链模式的关键在于,每个处理者都知道它的下一个处理者是谁,并且可以在必要时将请求传递给下一个处理者。责任链模式常用于需要按顺序处理请求、避免请求发送者和接收者直接耦合、以及动态指定处理对象的场景。

责任链模式包含以下角色:

  1. 抽象处理者(Handler):定义一个处理请求的接口,通常包含一个指向下一个处理者的引用。它的作用是提供一个统一的处理方法声明,以便在不同的具体处理者之间传递请求。还声明了由于某个条件的约束,责任链的当前处理者不能处理该请求,因此必须将请求传递给下一个处理者。
  2. 具体处理者(Concrete Handler):实现抽象处理者接口,并具体判断是否能够处理接收到的请求。如果能够处理,它会进行相应的处理操作;如果不能处理,它则将请求传递给链上的下一个处理者。
  3. 客户端(Client):创建并提交请求对象,构建责任链,并将请求发送到责任链的第一个处理者。客户类不关心请求的具体处理细节和传递过程,它只负责启动请求的处理流程。

责任链模式优缺点:

优点:

  1. 解耦性:责任链模式将请求的发送者和接收者解耦,使得请求发送者无需知道请求的具体处理者,增强了系统的灵活性。
  2. 可扩展性:可以动态地添加、移除或修改处理者,而不需要修改客户端代码,方便对系统进行扩展和维护,且满足开闭原则。
  3. 提高了系统的灵活性:可以根据请求的内容动态地决定传递给哪个处理者,或者按照一定的顺序依次传递。
  4. 简化对象:每个具体处理者只需关注自己的处理逻辑,以及如何将请求传递给下一个处理者,处理者之间是相互独立的,从而使得对象职责更加清晰,易于管理和维护。

缺点:

  1. 请求处理不确定性:由于责任链是依次传递请求的,如果链中的某个处理者没有正确处理请求,也没有将其传递给下一个处理者,那么该请求可能会被忽略。
  2. 性能影响:因为请求是依次传递的,所以链中的处理者数量越多,处理请求的时间就可能越长。特别是在链很长的情况下,性能问题会更加突出。
  3. 调试困难:责任链模式中请求的处理流程是动态的,可能会增加调试的难度,特别是责任链较长时,需要仔细跟踪请求的处理路径。
  4. 设计较复杂:在构建责任链时,需要确保每个处理者都知道其下一个处理者是谁,这增加了设计的复杂性。

使用场景

  1. 多个对象可以处理同一个请求:当一个请求可以被多个对象处理时,可以使用责任链模式将这些对象组织成一个链,每个对象都有机会处理该请求。
  2. 解耦请求的发送者和接收者:当客户端不需要知道请求的具体处理细节,只需要将请求发送到责任链上即可时,可以使用责任链模式来降低客户端与处理者的耦合度。
  3. 动态组织链:当需要根据运行时条件动态地添加或删除处理者时,责任链模式提供了一种灵活的方式来组织处理者。
  4. 扩展性要求较高:当系统需要支持多种不同的处理方式,并且希望能够方便地添加新的处理方式时,责任链模式可以帮助实现这种可扩展性。
  5. 需要对请求进行分阶段处理:当一个请求需要经过多个阶段进行处理时,可以使用责任链模式将每个阶段的责任分配给不同的处理者。
  6. 避免请求被单个对象阻塞:当一个请求的处理时间较长,不希望阻塞整个系统时,可以将请求的处理分散到多个对象中,使用责任链模式来实现异步处理。

以下举一个责任链模式的例子:

下面通过一个简单的例子来演示。

下面以公司员工请假审批流程为例。我们假设有组长,主管和老板。如果一位员工请假,需要根据请假日期,需要经过这三个人审批,但请假天数的不同就需要不同的审批者。

创建抽象处理者对象(Handler)

java 复制代码
public abstract class Approver {
    Approver next;

    //设置下一个审批者
    public void setNext(Approver next) {
        this.next = next;
    }

    //审批请求
    public abstract void approve(Integer request);
}

创建三个具体处理者(Concrete Handler),分别对应组长,主管和老板

java 复制代码
public class Leader extends Approver {

    @Override
    public void approve(Integer request) {
        if (request <= 1) {
            System.out.println("该员工请假" + request + "天,组长可以审批请假");
        } else {
            if (next != null) {
                System.out.println("请假天数过多,组长审批不了,交由上级领导审批");
                next.approve(request);
            }
        }
    }
}
java 复制代码
public class Supervisor extends Approver {

    @Override
    public void approve(Integer request) {
        if (request <= 3) {
            System.out.println("该员工请假" + request + "天,主管可以审批请假");
        } else {
            if (next != null) {
                System.out.println("请假天数过多,主管审批不了,交由上级领导审批");
                next.approve(request);
            }
        }
    }
}
java 复制代码
public class Boss extends Approver {

    @Override
    public void approve(Integer request) {
        if (request > 3) {
            System.out.println("该员工请假" + request + "天,老板可以审批请假");
        } else {
            if (next != null) {
                System.out.println("请假天数过多,老板审批不了,交由上级领导审批");
                next.approve(request);
            }
        }
    }
}

创建客户端(Client)

java 复制代码
public class Client {
    public static void main(String[] args) {
        Approver leader = new Leader();
        Approver supervisor = new Supervisor();
        Approver boss = new Boss();

        //组织责任链
        leader.setNext(supervisor);
        supervisor.setNext(boss);

        //发起请求
        leader.approve(5);
    }
}

输出结果如下所示:

java 复制代码
请假天数过多,组长审批不了,交由上级领导审批
请假天数过多,主管审批不了,交由上级领导审批
该员工请假5天,老板可以审批请假

在上述例子中,每个审批者对应一个Approver对象,组长、主管和老板分别继承自Approver类。每个Approver对象都有一个next属性,代表下一个审批者,这样就形成了一个责任链。在处理请求的时候,如果当前审批者可以处理请求,就处理请求;否则将请求传递给下一个审批者处理。

可以看到,在这个例子中,如果请假天数小于等于1天,组长就处理请求;如果请假天数小于等于3天,主管就处理请求;如果请假天数大于3天,老板就处理请求。如果当前审批者无法处理请求,就将请求传递给下一个审批者处理,直到所有审批者都处理完成。

总而言之:

责任链模式是一种行为型设计模式,它通过将请求的发送者和接收者解耦,允许多个对象有机会处理请求,从而提供了更大的灵活性和可扩展性。

在责任链模式中,请求沿着一个链传递,直到有一个对象处理它为止。这种模式定义了一个处理请求的接口,通常包含一个处理请求的方法和一个指向下一个处理者的引用。具体处理者实现这个接口,并定义了对请求的处理方式。客户端只需将请求发送到责任链上,无需关心请求的具体处理细节和传递过程。

责任链模式的优点是增加了系统的灵活性,允许动态组织链,支持多个对象处理请求,简化了对象的结构和职责。缺点是可能导致性能问题,调试困难,可能导致循环调用,且不保证请求一定会被处理。

责任链模式适用于多个对象可以处理同一个请求、解耦请求的发送者和接收者、动态组织链、扩展性要求较高、需要对请求进行分阶段处理以及避免请求被单个对象阻塞的场景。

总的来说,责任链模式提供了一种灵活的方式来处理请求,允许多个对象共同处理一个请求,同时保持系统的灵活性和可扩展性。但在使用时需要注意其潜在的性能问题和调试难度。

以上代码下载请点击该链接:https://github.com/Yarrow052/Java-package.git

相关推荐
天下烛火空明4 分钟前
【代码随想录算法训练营第42期 第三十天 | LeetCode452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间】
java·算法·哈希算法
m0_4802277015 分钟前
计算机基础知识总结(八股文--计算机网络、操作系统、数据库、c++、数据结构与算法)
java·数据结构·数据库·c++·计算机网络·mysql·算法
青年有志39 分钟前
Intellij Idea + Git 完美实战!
java·git·intellij-idea
hxj199108141 小时前
如何自己通过java实现一个rpc框架?简单例子
java·开发语言·rpc
易云码1 小时前
neo4j+es知识库管理系统(源码)
java·vue.js·后端·低代码·neo4j
当归10241 小时前
SQL 对版本进行排序遇到的问题
java·数据库·sql
NullPointerExpection1 小时前
java 使用 aws s3 sdk 通过分段下载来实现 html 页面 video 的断点播放、拖动进度播放
java·html·h5·aws·video·javaee
卡戎-caryon1 小时前
【C++】13.特殊类的设计
java·开发语言·c++·算法
OKkankan2 小时前
数据在内存中的存储
java·c语言·开发语言·数据结构·c++·算法
初晴~2 小时前
【多线程】深入剖析线程安全问题
java·多线程·thread·线程安全