首页 > 其他分享 >责任链模式

责任链模式

时间:2024-10-08 13:49:54浏览次数:10  
标签:请求 处理 request 模式 责任 handleRequest nextHandler public

简介

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

标签:请求,处理,request,模式,责任,handleRequest,nextHandler,public
From: https://blog.csdn.net/Android_xue/article/details/142750705

相关文章

  • Python 代理模式:控制对象访问的智能中介
    在Python编程中,代理模式(ProxyPattern)是一种非常有用的设计模式,它在许多场景下能够为我们提供更加灵活和可控的对象访问方式。代理模式就像是一个中间人,它站在客户端和真实对象之间,代替真实对象处理请求,并且可以在这个过程中添加额外的逻辑,如权限验证、懒加载等。本文将深......
  • Python 享元模式:高效利用内存的设计模式
    在Python编程中,随着程序规模的增大和数据量的增加,内存管理变得至关重要。享元模式(FlyweightPattern)作为一种结构型设计模式,为我们提供了一种在某些场景下有效管理内存、提高系统性能的方法。本文将深入探讨Python中的享元模式,包括其概念、关键要点、实现方式、应用场景......
  • Python 外观模式:简化复杂系统交互的设计模式
    在软件开发过程中,随着系统规模的不断扩大和功能的日益复杂,子系统之间的交互可能变得错综复杂。Python中的外观模式(FacadePattern)提供了一种有效的解决方案,它能够简化这些复杂的交互,为客户端提供一个统一、易用的接口来访问系统。本文将深入探讨Python中的外观模式,详细阐......
  • Python 装饰器模式:增强函数与类的优雅之道
    在Python编程中,装饰器模式(DecoratorPattern)是一种强大且灵活的设计模式,它允许我们在不修改现有函数或类的结构的情况下,动态地添加额外的功能。这种模式遵循了开放-封闭原则,即软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。本文将深入探讨Python中的装饰器模式,......
  • Mybatis——SqlSessionFactoryBuilder工厂模式
    Mybatis——SqlSessionFactoryBuilder工厂模式工厂模式题外话合集总览:Mybatis框架梳理  说一下我的理解:设计模式是对项目工程中代码结构的设计和抽象,有了这种设计和抽象,系统才有了扩展性。记住了模式的角色、组成、UML类图,只是记住了模式的形,类似武术中的拳法套......
  • 今天终于解决lazarus debug模式为GDB时中文变量显示出错的问题
    之前已修复fpdebug中文变量的Bug,但GDB还存在问题(提示:Invalidcharacterxxxxinexpression)修复步骤:打开lazarus/components/lazdebuggergdbmi/gdbmidebugger.pp,按红色代码修改。在TGDBMIExceptionInfo=record后添加functionischinese(s:string):string(1790行):TGD......
  • 小绿书开启副业模式(保姆级教程)
     大家好,我是凡人。是一个不黑、不吹、不跟风、有知识、有骨气的五好小号主。好多小伙伴给我私信,问我有最近没有非常火爆的副业项目,现在很多赛道人满为患,有没有值得推荐的,别说还真有,可能大家都没注意到前段时间腾讯对微信小店的带货体系升级的新闻,其实这就是信息差。那这个......
  • IDEA 代码格式化快捷键设置 中文或者英文语言模式下的IDEA
    在IntelliJIDEA(Windows)中修改代码格式化的快捷键步骤如下:打开IntelliJIDEA,然后点击顶部菜单栏中的File>Settings(设置)在设置窗口中,依次展开Keymap(按键映射)部分。在Keymap页面,你可以看到一个搜索框,输入“FormatCode”(代码格式)来快速定位到格式化代码......
  • Observable(观察者)设计模式
    前言Observable设计模式存在于许多JavaAPI和响应式编程中。下面介绍Java中永恒的Observable模式。Observable设计模式用于许多重要的JavaAPI。一个众所周知的示例是使用ActionListenerAPI执行操作的JButton。在这个例子中,我们ActionListener在按钮上进行了监听或观察。单击......
  • Java中的外观模式
    Java中的外观模式综述本文总结外观模式的定义,特点,使用场景并给出了具体的示例.外观模式的定义外观模式(门面模式)是一种结构型设计模式.其主要目的是为复杂系统提供一个简化的接口.帮助客户端代码与系统的子系统进行交互,同时还可以省略大量的细节.这种设计模式可以称得......