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

责任链模式简介

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

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

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

责任链模式优缺点:
优点:

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

缺点:

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

使用场景

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

以下举一个责任链模式的例子:
下面通过一个简单的例子来演示。
下面以公司员工请假审批流程为例。我们假设有组长,主管和老板。如果一位员工请假,需要根据请假日期,需要经过这三个人审批,但请假天数的不同就需要不同的审批者。

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

public abstract class Approver {
    Approver next;

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

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

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

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);
            }
        }
    }
}
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);
            }
        }
    }
}
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)

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);
    }
}

输出结果如下所示:

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

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

总而言之:
责任链模式是一种行为型设计模式,它通过将请求的发送者和接收者解耦,允许多个对象有机会处理请求,从而提供了更大的灵活性和可扩展性。
在责任链模式中,请求沿着一个链传递,直到有一个对象处理它为止。这种模式定义了一个处理请求的接口,通常包含一个处理请求的方法和一个指向下一个处理者的引用。具体处理者实现这个接口,并定义了对请求的处理方式。客户端只需将请求发送到责任链上,无需关心请求的具体处理细节和传递过程。
责任链模式的优点是增加了系统的灵活性,允许动态组织链,支持多个对象处理请求,简化了对象的结构和职责。缺点是可能导致性能问题,调试困难,可能导致循环调用,且不保证请求一定会被处理。
责任链模式适用于多个对象可以处理同一个请求、解耦请求的发送者和接收者、动态组织链、扩展性要求较高、需要对请求进行分阶段处理以及避免请求被单个对象阻塞的场景。
总的来说,责任链模式提供了一种灵活的方式来处理请求,允许多个对象共同处理一个请求,同时保持系统的灵活性和可扩展性。但在使用时需要注意其潜在的性能问题和调试难度。


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

相关推荐

  1. 设计模式详解)——责任模式

    2024-07-14 04:50:03       21 阅读
  2. 设计模式-责任模式

    2024-07-14 04:50:03       51 阅读
  3. 设计模式——责任模式

    2024-07-14 04:50:03       52 阅读
  4. 设计模式责任模式

    2024-07-14 04:50:03       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 04:50:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 04:50:03       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 04:50:03       58 阅读
  4. Python语言-面向对象

    2024-07-14 04:50:03       69 阅读

热门阅读

  1. Vue3 关于scss预编译中:deep 其中的deep如何理解

    2024-07-14 04:50:03       22 阅读
  2. stm32使用通用定时器生成pwm

    2024-07-14 04:50:03       26 阅读
  3. 如何实现一个分布式锁

    2024-07-14 04:50:03       18 阅读
  4. BGP笔记的基本概要

    2024-07-14 04:50:03       23 阅读
  5. 在RHEL9.4上安装Python3.11环境

    2024-07-14 04:50:03       21 阅读
  6. Hypertable install of rhel6.0

    2024-07-14 04:50:03       22 阅读
  7. 60、基于浅层神经网络的数据拟合(matlab)

    2024-07-14 04:50:03       26 阅读
  8. conda激活的虚拟环境的python版本不对应

    2024-07-14 04:50:03       23 阅读
  9. 实变函数精解【4】

    2024-07-14 04:50:03       20 阅读
  10. react详解

    2024-07-14 04:50:03       28 阅读
  11. 第一节 SHELL脚本中的常用命令(7)

    2024-07-14 04:50:03       27 阅读
  12. Python中的lambda表达式

    2024-07-14 04:50:03       23 阅读
  13. WSGI 服务器教程:`full_dispatch_request` 方法解析

    2024-07-14 04:50:03       25 阅读
  14. Facebook Research 的 Ocean 框架用于AR和CV的C++库

    2024-07-14 04:50:03       18 阅读
  15. docker部署neo4j

    2024-07-14 04:50:03       22 阅读