责任链模式

简介

责任链模式(Chain of Responsibility Pattern)将链中每一个节点都看作一个对象,每个节点处理的请求均不同,且内部自动维护下一个节点对象。当一个请求从链式的首端发出时,会沿着责任链预设的路径依次传递到每一个节点对象,直至被链中的某个对象处理为止,属于行为型设计模式。

通用模板

  1. 创建抽象处理者:定义一个请求处理的方法,并维护一个下一处理节点Handler对象的引用。

    // 抽象处理者
    public abstract class Handler {
        protected Handler nextHandler;
    
        public void setNextHandler(Handler nextHandler) {
            this.nextHandler = nextHandler;
        }
    
        public abstract void handleRequest(String request);
    }
    
  2. 创建具体处理者:对请求进行处理,如果不感兴趣,则进行转发。

    // 具体处理者A
    public class ConcreteHandlerA extends Handler {
        @Override
        public void handleRequest(String request) {
            if ("requestA".equals(request)) {
                System.out.println(this.getClass().getSimpleName() + " deal with request:" + request);
                return;
            }
    
            if (this.nextHandler != null){
                this.nextHandler.handleRequest(request);
            }
        }
    }
    
    // 具体处理者B
    public class ConcreteHandlerB extends Handler {
        @Override
        public void handleRequest(String request) {
            if ("requestB".equals(request)) {
                System.out.println(this.getClass().getSimpleName() + " deal with request:" + request);
                return;
            }
    
            if (this.nextHandler != null){
                this.nextHandler.handleRequest(request);
            }
        }
    }
    

说明: 在上面代码中,我们把消息硬编码为String类型,而在真实业务中,消息是具备多样性的,可以是int、String或者自定义类型。因此,在上面代码的基础上,可以对消息类型进行抽象Request,增强了消息的兼容性。

模板测试

  1. 测试代码

    public class Client {
        public static void main(String[] args) {
            Handler handlerA = new ConcreteHandlerA();
            Handler handlerB = new ConcreteHandlerB();
            // 设置责任链
            handlerA.setNextHandler(handlerB);
            // 创建请求:我们把消息硬编码为String类型,而在真实业务中,
            // 消息是具备多样性的,可以是int、String或者自定义类型。
            // 因此,在上面代码的基础上,可以对消息类型进行抽象Request,增强了消息的兼容性。
            String request = "requestB";
            // 发送请求
            handlerA.handleRequest(request);
        }
    }
    
  2. 测试结果

    ConcreteHandlerB deal with request:requestB
    

应用场景

在日常生活中,责任链模式是比较常见的。我们平时处理工作中的一些事务,往往是各部门协同合作来完成某一个任务的。而每个部门都有各自的职责,因此,很多时候事情完成一半,便会转交到下一个部门,直到所有部门都审批通过,事情才能完成。还有我们平时说的“过五关,斩六将”其实就是闯关,也是责任链模式的一种应用场景。
责任链模式主要解耦了请求与处理,客户只需将请求发送到链上即可,不需要关心请求的具体内容和处理细节,请求会自动进行传递,直至有节点对象进行处理。责任链模式主要适用于以下应用场景。 (1)多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
(2)在不明确指定接收者的情况下,向多个对象中的一个提交请求。
(3)可动态指定一组对象处理请求。

优点

(1)将请求与处理解耦。
(2)请求处理者(节点对象)只需关注自己感兴趣的请求进行处理即可,对于不感兴趣的请求,直接转发给下一个节点对象。
(3)具备链式传递处理请求功能,请求发送者不需要知晓链路结构,只需等待请求处理结果即可。 (4)链路结构灵活,可以通过改变链路结构动态地新增或删减责任。
(5)易于扩展新的请求处理类(节点),符合开闭原则。

缺点

(1)责任链太长或者处理时间过长,会影响整体性能。
(2)如果节点对象存在循环引用,则会造成死循环,导致系统崩溃。

“生搬硬套”实战

场景描述

我们将使用责任链模式来处理员工请假申请的例子。在这个例子中,我们有三种类型的请假请求:病假、事假和年假。每个请求将根据请假天数和类型被不同的经理审批。

代码开发
  1. 实战中我们用自定义类来代替模板中的字符串,先自定义一个请假请求类:

    // 请假请求类
    public class LeaveRequest {
        private String type;
        private int days;
    
        public LeaveRequest(String type, int days) {
            this.type = type;
            this.days = days;
        }
    
        public String getType() {
            return type;
        }
    
        public int getDays() {
            return days;
        }
    }
    
  2. 创建抽象处理者(这里指请假请求的handler)

    // 请假请求处理者
    public abstract class LeaveRequestHandler {
        protected LeaveRequestHandler nextHandler;
    
        public LeaveRequestHandler setNext(LeaveRequestHandler handler) {
            this.nextHandler = handler;
            return handler;
        }
    
        public abstract void handleRequest(LeaveRequest request);
    }
    
  3. 创建具体处理者(这里指病假处理者、事假处理者以及年假处理者)

    // 病假处理者
    public class SickLeaveHandler extends LeaveRequestHandler {
        @Override
        public void handleRequest(LeaveRequest request) {
            if ("Sick".equals(request.getType())) {
                System.out.println("Sick leave request is handled by " + getClass().getSimpleName());
            } else {
                if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                }
            }
        }
    }
    
    // 事假处理者
    public class PersonalLeaveHandler extends LeaveRequestHandler {
        @Override
        public void handleRequest(LeaveRequest request) {
            if ("Personal".equals(request.getType()) && request.getDays() <= 5) {
                System.out.println("Personal leave request is handled by " + getClass().getSimpleName());
            } else {
                if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                }
            }
        }
    }
    
    // 年假处理者
    public class AnnualLeaveHandler extends LeaveRequestHandler {
        @Override
        public void handleRequest(LeaveRequest request) {
            if ("Annual".equals(request.getType())) {
                System.out.println("Annual leave request is handled by " + getClass().getSimpleName());
            } else {
                if (nextHandler != null) {
                    nextHandler.handleRequest(request);
                }
            }
        }
    }
    

至此,我们就通过“生搬硬套”责任链模式的模板设计出一套请假申请的案例,接下来我们进行测试:

  • 测试代码

    public class Client {
        public static void main(String[] args) {
            LeaveRequestHandler sickHandler = new SickLeaveHandler();
            LeaveRequestHandler personalHandler = new PersonalLeaveHandler();
            LeaveRequestHandler annualHandler = new AnnualLeaveHandler();
    
            // 设置责任链
            sickHandler.setNext(personalHandler).setNext(annualHandler);
    
            // 创建请假请求
            LeaveRequest sickLeave = new LeaveRequest("Sick", 3);
            LeaveRequest personalLeave = new LeaveRequest("Personal", 4);
            LeaveRequest annualLeave = new LeaveRequest("Annual", 7);
    
            // 发送请求
            sickHandler.handleRequest(sickLeave);
            sickHandler.handleRequest(personalLeave);
            sickHandler.handleRequest(annualLeave);
        }
    }
    
  • 测试结果

    Sick leave request is handled by SickLeaveHandler
    Personal leave request is handled by PersonalLeaveHandler
    Annual leave request is handled by AnnualLeaveHandler
    

总结

责任链模式(Chain of Responsibility)是一种处理请求的模式,它让多个处理器都有机会处理该请求,直到其中某个处理成功为止。责任链模式把多个处理器串成链,然后让请求在链上传递:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SunnyRivers

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值