7.设计模式之责任链模式

news/2024/5/19 12:55:42 标签: 设计模式, 责任链模式, java

前言

责任链,即将能够处理同一类请求的对象连成一条链,所提交的请求沿着链传递, 链上的对象逐个判断是否有能力处理该请求,如果能则处理,如果不能则传递给链上的下一个对象。为了避免请求发送者与多个请求处理者耦合在一起, 将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链; 当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。

客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程, 所以责任链将请求的发送者和请求的处理者解耦了。责任链是一种对象行为型模式

1. 责任链中的角色

1.1 抽象处理者

定义一个处理请求的接口,包含抽象处理方法和一个后继连接。

1.2 具体处理者

实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。

1.3 客户类

创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。

1.4 图示

在这里插入图片描述

2. 代码示例

2.1 定义抽象处理者

java">package com.wanlong.design_pattern.action.chainOfResponsibility;

/**
 * @author wanlong
 * @version 1.0
 * @description:
 * @date 2022/9/19 17:39
 */
public abstract class Leader {
    private Leader next;

    public Leader getNext() {
        return next;
    }

    public void setNext(Leader next) {
        this.next = next;
    }

    //处理请求的方法
    public abstract void handleRequest(int LeaveDays);
}

2.2 定义具体处理者

2.2.1 定义具体处理者1

java">package com.wanlong.design_pattern.action.chainOfResponsibility;

/**
 * @author wanlong
 * @version 1.0
 * @description: 班主任责任链节点
 * @date 2022/9/19 17:40
 */

public class ClassAdviser extends Leader {
    @Override
    public void handleRequest(int LeaveDays) {
        if (LeaveDays <= 2) {
            System.out.println("班主任批准您请假" + LeaveDays + "天。");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(LeaveDays);
            } else {
                System.out.println("请假天数太多,没有人批准该假条!");
            }
        }
    }
}


2.2.2 定义具体处理者2

java">package com.wanlong.design_pattern.action.chainOfResponsibility;

/**
 * @author wanlong
 * @version 1.0
 * @description: 系主任责任链节点
 * @date 2022/9/19 17:41
 */


public class DepartmentHead extends Leader {
    @Override
    public void handleRequest(int LeaveDays) {
        if (LeaveDays <= 7) {
            System.out.println("系主任批准您请假" + LeaveDays + "天。");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(LeaveDays);
            } else {
                System.out.println("请假天数太多,没有人批准该假条!");
            }
        }
    }
}

2.2.3 定义具体处理者3

java">package com.wanlong.design_pattern.action.chainOfResponsibility;

/**
 * @author wanlong
 * @version 1.0
 * @description: 院长责任链节点
 * @date 2022/9/19 17:41
 */
public class Dean extends Leader {
    @Override
    public void handleRequest(int LeaveDays) {
        if (LeaveDays <= 10) {
            System.out.println("院长批准您请假" + LeaveDays + "天。");
        } else {
            if (getNext() != null) {
                getNext().handleRequest(LeaveDays);
            } else {
                System.out.println("请假天数太多,没有人批准该假条!");
            }
        }
    }
}

2.3 定义客户类

java">package com.wanlong.design_pattern.action.chainOfResponsibility;

import org.junit.Test;

/**
 * @author wanlong
 * @version 1.0
 * @description: 责任链模式调用
 * @date 2022/9/19 17:39
 */
public class Client {

    @Test
    public void test() {

        //组装责任链
        Leader leader1 = new ClassAdviser();
        Leader leader2 = new DepartmentHead();
        Leader leader3 = new Dean();
        leader1.setNext(leader2);
        leader2.setNext(leader3);
        //提交请求
        leader1.handleRequest(8);
    }

}

运行结果:
院长批准您请假8天。

3. 总结

3.1 优缺点

3.1.1 优点

  1. 由于责任链的创建完全在客户端,使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
  2. 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
  3. 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
  4. 责任分担。 每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则

3.1.2 缺点

  1. 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
  2. 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响
  3. 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错, 如可能会造成循环调用。

3.2 使用场景

  1. 有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。
  2. 动态指定一组对象处理请求,或添加新的处理者。
  3. 在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

3.3 常见框架使用

  1. Java中,异常机制就是一种责任链模式。 一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch。
  2. Javascript语言中,事件的冒泡和捕获机制。
  3. Servlet开发中,过滤器的链式处理
  4. Struts2中,拦截器的调用也是典型的责任链模式
  5. 流程引擎activiti ,camunda通过流程控制业务流转
  6. shiro 过滤器链

3.4 注意事项

3.4.1 模式的扩展

职责链模式存在以下两种情况:

  1. 纯的职责链模式: 一个请求必须被某一个处理者对象所接收,且一个具体处理者对某个请求的处理只能采用以下两种行为之一:自己处理(承担责任);把责任推给下家处理。
  2. 不纯的职责链模式: 允许出现某一个具体处理者对象在承担了请求的一部分责任后又将剩余的责任传给下家的情况,且一个请求可以最终不被任何接收端对象所接收。

以上,本人菜鸟一枚,如有问题,请不吝指正。


http://www.niftyadmin.cn/n/315010.html

相关文章

springboot工作原理解析

Spring Boot 是基于 Spring 框架的快速开发框架&#xff0c;它的目标是简化 Spring 应用程序的搭建和开发过程。Spring Boot 通过自动配置、快速启动、独立部署、多种数据源支持、集成测试等功能&#xff0c;使用springboot可快速构建高效、可靠的程序 目录 1. 自动配置1.1 Spr…

AndroidStudio-学习笔记之多级目录功能的设计与开发

多级目录功能的设计与开发 演示效果需求描述开发预计前端后端 前端开发多级目录的UI小框架前端xml前端代码---本地demo版前端代码---服务器版逻辑说明 后端开发表设计书写接口 演示效果 需求描述 根据需求&#xff0c;为用户展示多级目录(目前设计的为4级目录)&#xff0c;并在…

rust 第五章 —— trait详解

文章目录 前言一、初识Trait二、Trait的基本用法三、常见用法以及代码细节1.常见的注解简化代码2.表达式简化代码前言 本系列教程目录可点击这里查看:Rust教程目录 本文主要详解Rust中Trait这个概念,之所以为它单开一个章节,就是因为它非常的重要。 如果与其它语言类比来…

边缘网关协议(BGP)的演进与发展

边缘网关协议(Border Gateway Protocol&#xff0c;BGP)是一种用于在网络边缘传输路由信息的协议。它被广泛用于骨干网络和接入网络中&#xff0c;用于在网络边缘路由流量&#xff0c;并确保不同的网络之间具有最佳的路由路径。BGP是由RIP协议发展而来的&#xff0c;但在实现和…

virtualbox ubuntu20.04集群网络配置

这个问题困扰我一年之久。 大三学期的课程&#xff0c;因为集群网络问题卡壳。当时查阅各种资料&#xff0c;百度几十篇文章&#xff0c;看博客&#xff0c;甚至是请教老师都没能解决&#xff0c;也因为这个问题导致Hadoop后面都没有实操学习。 今大四毕业之际&#xff0c;又…

vue3【使用axios并封装axios请求】

第一步&#xff1a;安装axios npm install axios 第二步&#xff1a;编写请求文件 新建request.js 简单的axios封装&#xff0c;里面相关提示信息&#xff0c;自己可以引入element-plus去添加 /**axios封装* 请求拦截、相应拦截、错误统一处理*/ import axios from axios; i…

JUC之Synchronized与Lock

Synchronized 称之为”同步锁 作用&#xff1a; 保证在同一时刻&#xff0c; 被修饰的代码块或方法只会有一个线程执行&#xff0c;以达到保证并发安全的效果 用法&#xff1a; 1.修饰方法&#xff1a;方法锁&#xff0c;锁的对象是当前对象 2.修饰静态方法&#xff1a;类锁…

生态、遥感、大气、水文水资源、地下水土壤、人工智能等多领域教程

理论讲解案例实战动手实操讨论互动 针对 生态农林、遥感、语言土壤、统计、人工智能等领域全套教程。包含:InVEST模型、DSSAT模型、CENTURY模型、CASA模型、SWH蒸散模型、BGC模型、MAXENT模型、CLM模式、CLUE模型、PROSAIL模型、Biomod模型、Hydrus模型、Meta分析、ArcGIS、MAT…