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

责任链模式(Chain of Responsibility Pattern)

  • [责任链模式(Chain of Responsibility Pattern)](#责任链模式(Chain of Responsibility Pattern))

责任链模式(Chain of Responsibility Pattern)

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

太抽象了,举个现实生活中的例子

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

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

责任链结构图

责任链模式概述

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

责任链模式涉及的角色

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

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

    public abstract void handleRequest(String request);
}
  1. 具体处理者(ConcreteHandler):实现了Handler接口的具体类。
java 复制代码
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):客户端创建具体的处理者对象,并根据需要将它们链接起来形成一条责任链。然后,客户端将请求传递给链中的第一个处理者。
java 复制代码
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类来表示审批请求:
java 复制代码
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接口,所有审批者都将实现这个接口:
java 复制代码
public interface Approver {
    void processRequest(ApprovalRequest request);
    Approver getNextApprover();
    void setNextApprover(Approver nextApprover);
}
  1. 我们为不同的审批级别创建具体的审批者类。例如,部门经理(DepartmentManager)、总监(Director)和CEO(ChiefExecutiveOfficer)
java 复制代码
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. 最后,我们可以编写一个客户端类来测试这个责任链:
java 复制代码
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());
    }
}

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

总结

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

相关推荐
坐吃山猪3 小时前
SpringBoot01-配置文件
java·开发语言
我叫汪枫4 小时前
《Java餐厅的待客之道:BIO, NIO, AIO三种服务模式的进化》
java·开发语言·nio
yaoxtao4 小时前
java.nio.file.InvalidPathException异常
java·linux·ubuntu
Swift社区5 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT6 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy6 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss8 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续8 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0448 小时前
ReAct模式解读
java·ai