当前位置: 首页 > article >正文

一个个顺序挨着来 - 责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)

  • 责任链模式(Chain of Responsibility Pattern)
    • 责任链模式(Chain of Responsibility Pattern)概述
      • 责任链结构图
      • 责任链模式概述
      • 责任链模式涉及的角色
    • talk is cheap, show you my code
    • 总结

责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许你将请求沿着处理者链条传递,直到有一个处理者能够处理它为止。这种模式避免了请求发送者和接收者之间的耦合,并且可以动态地指定一组处理者来处理请求。每个处理者都包含对下一个处理者的引用,如果当前处理者不能处理请求,它会将请求转发给下一个处理者。

太抽象了,举个现实生活中的例子
生活中,我们可能会遇到需要报销的生活场景。但是报销的时候,每个人的报销权限不一样。比如金额比较小的时候,你的领导就可以帮你审批;但是如果金额超过了你领导的审核范围,你的领导可能就把报销的交给他的上一层领导处理;他的上一层领导如果能处理就处理,处理不了,就沿着审批链条再往上进行审批。

责任链模式(Chain of Responsibility Pattern)概述

责任链结构图

在这里插入图片描述

责任链模式概述

  • 定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。
  • 目的:解耦请求的发送者与接收者,提供一个灵活的方式来处理请求,支持动态添加或移除处理逻辑。

责任链模式涉及的角色

  1. 抽象处理者(Handler):声明了所有具体处理者必须实现的方法,通常是handle()方法。此外,它还可能包含一个指向下一个处理者的引用。
public abstract class Handler {
    protected Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public abstract void handleRequest(String request);
}
  1. 具体处理者(ConcreteHandler):实现了Handler接口的具体类。
public class ConcreteHandlerA extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("A".equals(request)) {
            System.out.println("Handled by ConcreteHandlerA");
        } else {
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}

public class ConcreteHandlerB extends Handler {
    @Override
    public void handleRequest(String request) {
        if ("B".equals(request)) {
            System.out.println("Handled by ConcreteHandlerB");
        } else {
            if (successor != null) {
                successor.handleRequest(request);
            }
        }
    }
}
  1. 客户端(Client):客户端创建具体的处理者对象,并根据需要将它们链接起来形成一条责任链。然后,客户端将请求传递给链中的第一个处理者。
public class Client {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();

        // 构建责任链
        handlerA.setSuccessor(handlerB);

        // 发送请求
        handlerA.handleRequest("A"); // Handled by ConcreteHandlerA
        handlerA.handleRequest("B"); // Handled by ConcreteHandlerB
        handlerA.handleRequest("C"); // Not handled, no output or error
    }
}

talk is cheap, show you my code

我们还是利用本次要介绍的设计模式来实现我们给出的例子。

  1. 首先,我们定义一个ApprovalRequest类来表示审批请求:
public class ApprovalRequest {
    private double amount;
    private String description;
    private boolean isApproved = false;

    public ApprovalRequest(double amount, String description) {
        this.amount = amount;
        this.description = description;
    }

    public double getAmount() {
        return amount;
    }

    public String getDescription() {
        return description;
    }

    public boolean isApproved() {
        return isApproved;
    }

    public void setApproved(boolean approved) {
        isApproved = approved;
    }
}
  1. 接下来,我们定义一个Approver接口,所有审批者都将实现这个接口:
public interface Approver {
    void processRequest(ApprovalRequest request);
    Approver getNextApprover();
    void setNextApprover(Approver nextApprover);
}
  1. 我们为不同的审批级别创建具体的审批者类。例如,部门经理(DepartmentManager)、总监(Director)和CEO(ChiefExecutiveOfficer)
public class DepartmentManager implements Approver {
    private Approver nextApprover;
    private static final double LIMIT = 5000.0;

    public DepartmentManager() {
    }

    @Override
    public void processRequest(ApprovalRequest request) {
        if (request.getAmount() <= LIMIT) {
            System.out.println(request.getDescription() + " is approved by Department Manager.");
            request.setApproved(true);
        } else {
            if (nextApprover != null) {
                nextApprover.processRequest(request);
            } else {
                System.out.println(request.getDescription() + " was rejected.");
                request.setApproved(false);
            }
        }
    }

    @Override
    public Approver getNextApprover() {
        return nextApprover;
    }

    @Override
    public void setNextApprover(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }
}

public class Director implements Approver {
    private Approver nextApprover;
    private static final double LIMIT = 20000.0;

    // Similar methods as in DepartmentManager
    // ...
}

public class ChiefExecutiveOfficer implements Approver {
    private Approver nextApprover;

    // No limit for CEO, all requests will be approved or rejected here
    // Similar methods as in DepartmentManager and Director
    // ...
}
  1. 最后,我们可以编写一个客户端类来测试这个责任链:
public class Client {
    public static void main(String[] args) {
        ApprovalRequest request1 = new ApprovalRequest(4500, "Office supplies");
        ApprovalRequest request2 = new ApprovalRequest(12000, "New computer");
        ApprovalRequest request3 = new ApprovalRequest(25000, "Conference room renovation");

        Approver departmentManager = new DepartmentManager();
        Approver director = new Director();
        Approver ceo = new ChiefExecutiveOfficer();

        departmentManager.setNextApprover(director);
        director.setNextApprover(ceo);

        departmentManager.processRequest(request1);
        System.out.println("Request1 approved? " + request1.isApproved());

        departmentManager.processRequest(request2);
        System.out.println("Request2 approved? " + request2.isApproved());

        departmentManager.processRequest(request3);
        System.out.println("Request3 approved? " + request3.isApproved());
    }
}

在这个客户端类中,我们创建了三个审批请求,并设置了审批链。然后,我们依次处理这些请求,并打印出它们是否被批准。

总结

责任链可以帮助我们降低耦合度;增加灵活性;可以帮助我们更好地组织代码。我们上面实现地责任链模式是类似与拦截器的那种方式。责任链还可以设计为一些别的方式。责任链模式一般适用于日志记录;审批流程等等。


http://www.kler.cn/a/472593.html

相关文章:

  • IvorySQL 升级指南:从 3.x 到 4.0 的平滑过渡
  • 单元测试MockitoExtension和SpringExtension
  • Leecode刷题C语言之字符串中最大的3位相同数字
  • 在 PhpStorm 中配置命令行直接运行 PHP 的步骤
  • Cursor无限续杯——解决Too many free trials.
  • Leffa 虚拟试衣论文笔记
  • LabVIEW之树形控件
  • el-table 自定义表头颜色
  • HTML5 旋转动画(Rotate Animation)详解
  • k8s的ip地址分别都是从哪里来的
  • 【Uniapp-Vue3】v-model双向绑定的实现原理
  • 第30天:Web开发-PHP应用组件框架前端模版渲染三方插件富文本编辑器CVE审计
  • K-Means 聚类算法:用生活场景讲解机器学习的“分组”方法
  • INT301 Bio Computation
  • 基于 Python 的 PDF 动画翻页效果的阅读器实现
  • Android NDK开发入门2之适应idm环境
  • .NET AI 开发人员库 --AI Dev Gallery
  • Linux pget 下载命令详解
  • filebeat、kafka
  • 基于Android的疫苗预约系统
  • 腾讯云AI代码助手编程挑战赛-古诗词学习
  • WordPress静态缓存插件WP Super Cache与 WP Fastest Cache
  • Spring Boot集成RocketMQ
  • C++实现银行排队系统
  • 单片机-定时器中断
  • C++ 复习总结记录五