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

责任链模式简介

责任链模式定义

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

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

  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

相关推荐
m0_5719575836 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟4 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity5 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天5 小时前
java的threadlocal为何内存泄漏
java
caridle5 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^6 小时前
数据库连接池的创建
java·开发语言·数据库
苹果醋36 小时前
Java8->Java19的初步探索
java·运维·spring boot·mysql·nginx