首页 > 编程语言 >JAVA设计模式之责任链模式

JAVA设计模式之责任链模式

时间:2023-05-23 11:06:19浏览次数:32  
标签:JAVA 请求 处理 request 责任 设计模式 public name



文章目录

  • 一、责任链(Chain of Responsibility)模式
  • 二、责任链模式的结构
  • 三、源码
  • 四、纯的与不纯的责任链模式
  • 五、总结


一、责任链(Chain of Responsibility)模式

顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

这种模式和LinkedList的链状数据结构相识,节点之间有着联系。

责任链可能是一条直线、一个环链或者一个树结构的一部分。

比如:

JAVA设计模式之责任链模式_ide

二、责任链模式的结构

下面使用了一个责任链模式的最简单的实现。

  

JAVA设计模式之责任链模式_责任链模式_02

责任链模式涉及到的角色如下所示:

●  抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

●  具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

三、源码

import lombok.Builder;
import lombok.Data;

@Data
public class LeaveRequest {
    /**天数*/
    private int leaveDays;

    /**姓名*/
    private String name;

    public LeaveRequest(int leaveDays,String name){
        this.leaveDays = leaveDays;
        this.name = name;
    }
}

抽象处理者角色:

/**
 * 抽象处理者角色类
 */
public abstract class AbstractLeaveHandler {
    /**直接主管审批处理的请假天数*/
    protected int MIN = 1;
    /**部门经理处理的请假天数*/
    protected int MIDDLE = 3;
    /**总经理处理的请假天数*/
    protected int MAX = 30;

    /**领导名称*/
    protected String handlerName;

    /**下一个处理节点(即更高级别的领导)*/
    protected AbstractLeaveHandler nextHandler;

    /**设置下一节点*/
    public void setNextHandler(AbstractLeaveHandler handler){
        this.nextHandler = handler;
    }

    /**处理请假的请求,子类实现*/
    public abstract void handlerRequest(LeaveRequest request);
}

具体处理者角色:

/**
 * @description: 直接主管处理类
 */
public class LeaderLeaveHandler extends AbstractLeaveHandler{
    public LeaderLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    public void handlerRequest(LeaveRequest request) {
        if(request.getLeaveDays() <= this.MIN){
            System.out.println("直接主管:" + handlerName + ",已经处理;流程结束。");
            return;
        }

        if(null != this.nextHandler){
            this.nextHandler.handlerRequest(request);
        }else{
            System.out.println("审批拒绝!");
        }

    }
}
/**
 * @description: 部门经理处理类
 */
public class ManagerLeaveHandler extends AbstractLeaveHandler {

    public ManagerLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    public void handlerRequest(LeaveRequest request) {
        if(request.getLeaveDays() >this.MIN && request.getLeaveDays() <= this.MIDDLE){
            System.out.println("部门经理:" + handlerName + ",已经处理;流程结束。");
            return;
        }

        if(null != this.nextHandler){
            this.nextHandler.handlerRequest(request);
        }else{
            System.out.println("审批拒绝!");
        }
    }
}
/**
 * @description: 总经理处理类
 */
public class CEOLeaveHandler extends AbstractLeaveHandler {
    public CEOLeaveHandler(String name) {
        this.handlerName = name;
    }

    @Override
    public void handlerRequest(LeaveRequest request) {
        if(request.getLeaveDays() > this.MIDDLE && request.getLeaveDays() <= this.MAX){
            System.out.println("总经理:" + handlerName + ",已经处理;流程结束。");
            return;
        }

        if(null != this.nextHandler){
            this.nextHandler.handlerRequest(request);
        }else{
            System.out.println("审批拒绝!");
        }
    }
}

测试类:

public class ResponsibilityTest {
    public static void main(String[] args) {
        LeaveRequest request = new LeaveRequest(20,"李三");

        AbstractLeaveHandler leaderLeaveHandler = new LeaderLeaveHandler("县令");
        ManagerLeaveHandler managerLeaveHandler = new ManagerLeaveHandler("知府");
        CEOLeaveHandler ceoLeaveHandler = new CEOLeaveHandler("京兆尹");

        leaderLeaveHandler.setNextHandler(managerLeaveHandler);
        managerLeaveHandler.setNextHandler(ceoLeaveHandler);

        leaderLeaveHandler.handlerRequest(request);


    }
}

运行结果:

总经理:京兆尹,已经处理;流程结束。

四、纯的与不纯的责任链模式

一个纯的责任链模式要求一个具体的处理者对象只能在两个行为中选择一个:一是承担责任,而是把责任推给下家。不允许出现某一个具体处理者对象在承担了一部分责任后又 把责任向下传的情况。

在一个纯的责任链模式里面,一个请求必须被某一个处理者对象所接收;在一个不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。

纯的责任链模式的实际例子很难找到,一般看到的例子均是不纯的责任链模式的实现。

五、总结

责任链主要重在责任分离处理,让各个节点各司其职。
责任链上的各个节点都有机会处理事务,但是也可能不会受理请求。
责任链比较长,调试时可能会比较麻烦。
责任链一般用于处理流程节点之类的实际业务场景中。
Spring拦截器链、servlet过滤器链等都采用了责任链设计模式。

优点:
1、降低耦合度。它将请求的发送者和接收者解耦。
2、简化了对象。使得对象不需要知道链的结构。
3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。

缺点:
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
3、可能不容易观察运行时的特征,有碍于除错。

使用场景:
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。


标签:JAVA,请求,处理,request,责任,设计模式,public,name
From: https://blog.51cto.com/u_16125162/6330105

相关文章

  • 微信分享+java后台
    ​微信分享很多人都接触过,我只是把我自己的方法写了一下。不好之处,敬请原谅!先来一张流程图,很实用,也是网上找的,感谢这位博主。​编辑 公众号配置那些就不写了,直接上代码吧!1)、官方上面有相应的签名代码,下载下来就行 进入官方文档 https://mp.weixin.qq.com/wiki?t=resourc......
  • 支付宝APP支付(java后台版)
    ​本实例是基于springBoot框架编写  一、流程步骤      1.执行流程        当手机端app在支付页面时,调起服务端创建订单(自己公司业务接口)接口,后台把需要调起支付宝支付的参数返回给手机端,手机端得到参数后,调起支付宝支付环境支付,完成支付后后会调异......
  • Java开发Lombok使用详解
    转:https://www.jb51.net/article/198920.htm什么是LombokLombok是一款Java开发插件,可以通过它定义的注解来精简冗长和繁琐的代码,主要针对简单的Java模型对象(POJO)。好处就显而易见了,可以节省大量重复工作,特别是当POJO类的属性增减时,需要重复修改的Getter/Setter、构造器方法、eq......
  • Java开发笔记之将一个List拷贝到另一个List的问题
    0x00概述在对List数据进行不同的数据操作的时候,例如分支1将List按照A来排序,分支2将List按照B来排序,需要将List进行数据层面的拷贝; 0x01错误的操作仅仅是List的引用,并没拷贝List内的数据进行处理List<String>list1=newArrayList<>();List<String>list2=newArrayL......
  • 用chatGPT快速开发java后端功能
     接到一个紧急需求如图常规无非是建表,写接口,写测试类,最后造数据进行自测。突发奇想,要不用GPT4试一下快速写业务代码? 写句子1分钟,建表和得到代码1分钟第一步:建表,直接复制excel中内容到GPT中 第二步:要求转为下划线:  第三步:给出条件和想要的结果(下面第一幅图是自己写......
  • java.lang.IndexOutOfBoundsException: Invalid range
    报文:ERROR:17:38:36,099-TcLogger$IC_PrintStream.logButCheckForException:?java.lang.IndexOutOfBoundsExceptionjava.lang.IndexOutOfBoundsException:Invalidrange atjavax.swing.DefaultRowSorter.rowsUpdated(UnknownSource) atjavax.swing.DefaultRowSor......
  • 一篇文章告诉你什么是Java内存模型
    在上篇并发编程Bug起源:可见性、有序性和原子性问题,介绍了操作系统为了提示运行速度,做了各种优化,同时也带来数据的并发问题,定义在单线程系统中,代码按照顺序从上往下顺序执行,执行不会出现问题。比如一下代码:inta=1;intb=2;intc=a+b;程序从上往下执行,最终c的结果......
  • java学习日记20230522-TreeSet
    有序键值对集合publicclassTreeSetExercise{publicstaticvoidmain(String[]args){Integerinteger=newInteger(10);TreeSettreeSet=newTreeSet(newComparator(){@Overridepublicintcompare(Objecto1,Obj......
  • java学习日记20230522-集合选择原则
    1.判断存储的类型,一组对象【单列】或者一组键值对【双列】2.一组对象【单列】:collection的子类:允许重复:List的某个实现类:增删多LinkedList(底层维护的是双向链表)                                改查多ArrayList(底层维护的是object类型的可......
  • JavaScript函数
    1函数定义使用function关键字来定义,即functionfName(para,...){statment;...;},可使用在函数声明语句与函数定义表达式这两种形式中函数名称标识符fName。是函数声明语句必需的部分。它的用途就像变量的名字,新定义的函数对象会赋值给这个变量但对函数定义表达式来说......