设计模式-责任链模式

【Java设计模式】Java设计模式之(五)责任链模式(Chain of Responsibility Pattern) 本文目录 一、责任链模式介绍 二、代码实现 2.1 业务逻辑 2.2 代码实现 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。 在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。 一、责任链模式介绍 意图:避免请求发送者与接收者耦合在一起,让多个对象都 阅读详情

责任链模式

定义

把链中每一个节点看做一个对象,每个节点处理的请求都不一样。

内部自动维护一个下一个节点对象。

当一个请求从链的请求首段发出的时候,会沿着链的路径一次传递给每一个节点对象,直到某个对象就结束。

行为模式

生活中的场景

  • 生活中的审批流程
  • 部门的申请

适用场景

  • 多个对象可以处理同一个请求,单具体由那个对象处理则在运动时动态决定
  • 在不明白知道你个接受者的情况下,向多个对象中的一个提交一个请求
  • 可以动态指定一组对象处理请求

通用类图

image-20210106221307543

可以看到责任链主要包含两种角色:

  • Handler
    • 抽象处理者
      • 定义一个请求处理的方法,并且维护一个下一个处理节点Handler的引用
  • ConcreteHandler
    • 具体处理者
      • 对请求进行处理,如果不感兴趣,则进行转发
public class Test {
  public static void main(String[] args) {
    Handler handlerA = new ConcreteHandlerA();
    Handler handlerB = new ConcreteHandlerB();
    handlerA.setNextHanlder(handlerB);
    handlerA.handleRequest("requestB");
  }
}

责任链模式和建造者模式一起使用

可以看到上述每次需要自己来new对应的Handler链路较长的时候,我们使用会非常繁琐,可以通过建造者模式,自动链式组装

参考AQS

private Node enq(final Node node) {
  for (;;) {
    Node t = tail;
    if (t == null) { // Must initialize
      if (compareAndSetHead(new Node()))
        tail = head;
    } else {
      node.prev = t;
      if (compareAndSetTail(t, node)) {
        t.next = node;
        return t;
      }
    }
  }
}
public abstract class Handler<T> {
  protected Handler next;
  public void next(Handler next){ this.next = next;}

  public abstract void doHandler(Member member);

  public static class Builder<T>{
    private Handler<T> head;
    private Handler<T> tail;

    public Builder<T> addHandler(Handler handler){
      //            do {
      if (this.head == null) {
        this.head = this.tail = handler;
        return this;
      }
      this.tail.next(handler);
      this.tail = handler;
      //            }while (false);//真正框架中,如果是双向链表,会判断是否已经到了尾部
      return this;
    }

    public Handler<T> build(){
      return this.head;
    }

  }
}

修改上述代码变成了这样

public class Test {
  public static void main(String[] args) {
    Handler handler=  new Handler.
      Builder().
      addHandler(new ConcreteHandlerA()).
      addHandler(new ConcreteHandlerB()).build();

    handler.handleRequest("requestB");
  }
}

Netty pipline

源码中的体现

FilterChain

public interface FilterChain {

  public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException;
}

我们可以通过FilterChain来对请求做过滤

public class MockFilterChain implements FilterChain {

  public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
    Assert.notNull(request, "Request must not be null");
    Assert.notNull(response, "Response must not be null");
    Assert.state(this.request == null, "This FilterChain has already been called!");

    if (this.iterator == null) {
      this.iterator = this.filters.iterator();
    }

    if (this.iterator.hasNext()) {
      Filter nextFilter = this.iterator.next();
      nextFilter.doFilter(request, response, this);
    }

    this.request = request;
    this.response = response;
  }
}

例如MockFilterChain,请求一个一个来执行

通过线程分发,processor这样能够快速处理,见并发编程

Netty Pipline

可以看到Dubbo对于netty的使用

org.apache.dubbo.remoting.transport.netty4.NettyServer#doOpen

protected void doOpen() throws Throwable {
  bootstrap = new ServerBootstrap();

  bossGroup = NettyEventLoopFactory.eventLoopGroup(1, "NettyServerBoss");
  workerGroup = NettyEventLoopFactory.eventLoopGroup(
    getUrl().getPositiveParameter(IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS),
    "NettyServerWorker");

  final NettyServerHandler nettyServerHandler = new NettyServerHandler(getUrl(), this);
  channels = nettyServerHandler.getChannels();

  bootstrap.group(bossGroup, workerGroup)
    .channel(NettyEventLoopFactory.serverSocketChannelClass())
    .option(ChannelOption.SO_REUSEADDR, Boolean.TRUE)
    .childOption(ChannelOption.TCP_NODELAY, Boolean.TRUE)
    .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
    .childHandler(new ChannelInitializer<SocketChannel>() {
      @Override
      protected void initChannel(SocketChannel ch) throws Exception {
        // FIXME: should we use getTimeout()?
        int idleTimeout = UrlUtils.getIdleTimeout(getUrl());
        NettyCodecAdapter adapter = new NettyCodecAdapter(getCodec(), getUrl(), NettyServer.this);
        if (getUrl().getParameter(SSL_ENABLED_KEY, false)) {
          ch.pipeline().addLast("negotiation",
                                SslHandlerInitializer.sslServerHandler(getUrl(), nettyServerHandler));
        }
        ch.pipeline()
          .addLast("decoder", adapter.getDecoder())
          .addLast("encoder", adapter.getEncoder())
          .addLast("server-idle-handler", new IdleStateHandler(0, 0, idleTimeout, MILLISECONDS))
          .addLast("handler", nettyServerHandler);
      }
    });
  // bind
  ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
  channelFuture.syncUninterruptibly();
  channel = channelFuture.channel();

}

我们可以通过pipeline().addLast()一直调用追加对应的Handler,查看他的设计

io.netty.channel.DefaultChannelPipeline#addLast(io.netty.util.concurrent.EventExecutorGroup, java.lang.String, io.netty.channel.ChannelHandler)

private void addLast0(AbstractChannelHandlerContext newCtx) {
  AbstractChannelHandlerContext prev = tail.prev;
  newCtx.prev = prev;
  newCtx.next = tail;
  prev.next = newCtx;
  tail.prev = newCtx;
}

实际上在内部维护了一个双向链表,在处理的时候也会严重这个链表一直往下传递

优缺点

优点

  • 请求和处理解耦
  • 请求矗立着只需要关注自己感兴趣的请求进行处理就行了,对于不感兴趣的请求,直接转发给下一级节点对象
  • 具备链式传递处理请求功能,请求发送者不需要知道链路结构,只需要等待请求处理结果
  • 链路结构灵活,可以通过改变链路结构动态的新增或者删减责任链
  • 易于扩展新的请求处理类,符合开闭原则

缺点

  • 责任链过长,影响整体性能
    • 每个请求都是从链头到链尾,特别是在链路非常长的时候,性能是一个很大的问题
  • 调试非常不方便,尤其是链路比较长的时候,环节比较多的时候,因为采用了类似于递归的方式
    • 调试的时候逻辑比较复杂
  • 如果节点存在循环引用,容易造成死循环,系统崩溃

权限校验中,大量使用责任链

Spring Security ,Shiro

注意事项

  • 链路中的节点数量需要控制,要避免出现超长链的情况
    • 一般是在Handler中设置一个最大节点数量,在setNext的时候判断是否超过阈值,超过则不允许建立,避免无意识破坏系统性能

      我的笔记仓库地址gitee 快来给我点个Star吧

柔性OLED屏幕绿线故障的激光修复技术解析 OLED显示技术作为新一代显示方案,其主动矩阵驱动原理通过TFT背板控制每个像素的发光。在柔性屏幕应用中,微米级数据线路的物理损伤会导致显示异常,表现为贯穿屏幕的绿线故障。激光微焊技术凭借其微米级加工精度,成为修复这类精密电路损伤的理想方案。该技术通过纳秒级脉冲激光实现金属线路的精准重熔,在手机维修、显示面板制造等领域具有重要应用价值。特别是在折叠屏、曲面屏等柔性显示设备维修中,激光修复技术能有效解决因反复弯折导致的数据线断裂问题,配合光学定位系统和参数优化,修复成功率可达85%以上。 阅读详情

相关推荐

Frida实战:高效dump Android内存中的so文件与修复技巧

本文详细介绍了使用Frida工具dump Android内存中已解密so文件的实战技巧。针对加固应用静态分析失效的痛点,文章提供了从环境搭建、使用frida_dump脚本自动化抓取内存数据,到利用SoFixer工具修复ELF文件结构的完整流程,帮助逆向分析人员高效获取可分析的so文件。

tt34567的博客 527

【设计模式组合拳】建造者+责任链模式

公众号:WarmSmile 全文字数:1400+ 阅读时间:5分钟 建造者模式 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。 介绍 意图: 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 主要解决: 主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各.

Longines____的博客 1744

TwinCAT3实战:从零搭建倍福PLC的Modbus-TCP Server

本文详细介绍了如何使用TwinCAT3从零搭建倍福PLC的Modbus-TCP Server,包括环境准备、工程配置、参数设置、客户端连接测试及常见问题排查。通过实战步骤和实用技巧,帮助工程师快速掌握倍福PLC与Modbus-TCP的通信实现,提升工业自动化项目的开发效率。

weixin_30797199的博客 173

巧用『责任链模式』来优化参数多重校验,非常优雅!

背景最近在做需求,写一个方法,先在前面做验证,if不满足A条件则return,if不满足B条件则return...一共写了5个验证,等验证通过以后才执行下面的逻辑,这个也没问题。过了一阵产品提了需求,跟这个方法类似,我又把这个方法copy了一份,只不过验证条件稍微有点不一样,要变成6个验证了。这时候我就发现有三个问题,第一重复代码,相同的A条件B条件C条件写了两份,没有复用。第二,“头重脚轻”,比...

Java精选 2366

SOC Boot学习(二)——JTAG Debug介绍

JTAG(Joint Test Action Group ,联合测试行动小组 ) 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。JTAG 技术是一种嵌入式调试技术,它在芯片内部封装了专门的测试电路 TAP ( Test Access Port ,测试访问口),通过专用的 JTAG 测试工具对内部节点进行测试。如今大多数比较复杂的器件都支持 JTAG 协议,如 ARM 、 DSP 、 FPGA 器件等。

yttt的博客 1605

保姆级教程:在Ubuntu 20.04上从源码编译Apollo自动驾驶平台(含GPU环境配置)

本文提供了一份详细的Ubuntu 20.04上从源码编译Apollo自动驾驶平台的保姆级教程,包括GPU环境配置、Docker部署和编译构建等关键步骤。通过实战经验和避坑指南,帮助开发者高效完成Apollo平台的编译和验证,适用于自动驾驶技术研究和应用开发。

weixin_30876945的博客 407

这才是责任链模式的优雅使用方式

1 使用责任链模式设计热插拔权限控制 本文节选自《设计模式就该这样学》作者 谭勇德(Tom) 首先创建一个实体类Member。 public class Member { private String loginName; private String loginPass; private String roleName; public Member(String loginName, String loginPass) { this.loginNam

Tom弹架构 988

【从0到1实战】C# WinForm开发工业级PLC监控系统(完整串口+Modbus RTU/TCP+数据库存储+源码+避坑指南)

做C#工控上位机开发的工程师,尤其是刚入行的新人,最核心的刚需就是开发一套完整的PLC监控系统。这也是工控领域最基础、最核心、应用最广的项目类型——小到单台PLC的设备测控,大到整线的产线监控,本质都是「上位机与PLC通讯,实现数据采集、参数下发、状态监控、数据存储」。碎片化的知识点学了很多,串口会用了、Modbus协议看了、数据库也懂点,但是始终无法把这些知识点串联起来,做出一套能落地的工业级PLC监控系统。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1559

设计模式-责任链模式(Chain of Responsibility)

责任链模式是一种面向对象设计模式,该模式中包含了一系列处理对象和命令对象。每个处理对象都有能力决定自己可以处理哪些命令对象,如果遇到无法处理的命令对象,它会将请求传递给下一个处理对象。这种模式的核心在于避免请求发送者与接收者之间的紧密耦合,让多个对象都有可能接收请求,并将这些对象连接成一条链,沿着这条链传递请求,直到有对象处理它为止。以公司员工请假为例,员工的请假请求可能有多个领导可以批准,但每个领导的批准权限不同。员工需要根据自己要请假的天数去找对应的领导签名。这就是责任链模式的一个生动实例。

miaoyl的博客 1万+

YOLOv8改进 | 主干网络 | 增加网络结构增强小目标检测能力【独家创新——附结构图】

YOLOv8改进,小目标检测,yolov8

kay_545 6019

MALTAB程序利用质心法去寻峰

质心法的优点是简单易实现且计算速度快,适用于数据点较少或峰值较明显的情况。然而,对于复杂的数据或多峰曲线,质心法可能无法准确识别所有峰值,因此在这些情况下可能需要使用更复杂的峰值检测算法。质心法(Centroid Method)是一种寻找峰值的方法,其基本原理是通过计算数据窗口内的质心位置来确定峰值的位置。质心是指在一维数据中,按照数据的幅值对位置进行加权平均的结果,即质心位置为数据幅值加权平均值的位置。变量定义了计算质心的窗口大小。最后,绘制了找到的峰值位置和幅值点,并显示了找到的峰值位置和幅值的结果。

走向CTO的路上... 1345

【设计模式】责任链模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

一、责任链模式简介、 二、责任链模式相关设计模式、 三、责任链模式 代码示例、 1、用户账户类、 2、校验器父类、 3、用户名校验器、 4、密码校验器、 5、电话号码校验器、 6、运行测试、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 8590

西南科技大学模拟电子技术实验七(集成运算放大器的非线性应用)预习报告

将电位器Rp调至中心位置,用双综示波器观察并绘制方波U0的波形,测量其幅值和频率;将电位器RP调至中心位置,用示波器观察并绘制锯齿波U0的波形,记录;示波器基线调零,Ui输入1000HZ、幅值为2V的正弦信号,观察并记录Ui与U0波形,读出图中波形跳变时的Ui临界值;用万用表电位器RP调至预测结果位置,用示波器观察并描绘三角波输出U0及方波输出uo’,测其幅值、频率及Rp值,记录之。示波器基线调零,U输入1000HZ、幅值为2V的正弦信号,观察UI与U0波形。理论算法公式:当Ui

Welcome To My6n Blog 3936

设计模式-责任链模式-Chain of Responsibility Pattern

创建一个抽象基类,定义处理请求的接口和设置下一个处理者的指针。

wesigj的博客 2386

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【设计模式】责任链模式(Chain of Responsibility Pattern)

责任链模式()是将链中的每一个节点看做成一个对象,每个节点处理的请求均不同,且内部自动维护一个下一个节点对象,当一个请求从链式的首端发出时,会沿着链路的路径一次传递给每一个节点对象,直至有对象处理这个请求为止。责任链模式是一种行为型设计模式。...

老男孩的架构路 538

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

设计模式中的责任链模式(Chain of Responsibility Pattern)

在软件开发中,经常会遇到需要按照顺序处理请求的情况,例如日志处理、权限控制、审批流程等。如果使用硬编码的 `if-else` 结构,代码将变得复杂且难以扩展。 **责任链模式(Chain of Responsibility Pattern)** 提供了一种**将请求的处理者组织成链式结构**的方法,使请求可以**沿着责任链传递,直到被某个处理者处理**,从而提高代码的灵活性和可扩展性。本文将详细介绍责任链模式的概念、应用场景,并通过 Python 代码示例展示其实现方式。

2491

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

设计模式之责任链模式(Chain of Responsibility Pattern)

What: 责任链模式也叫职责链模式。为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。 Why: 优点: 1.降低耦合度。它将请求的发送者和接收者解耦。 2.增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 缺点: 1.责任...

qq_37212210的博客 503

Java设计模式——责任链模式【Chain of Responsibility Pattern】

Java设计模式、责任链模式、Chain of Responsibility Pattern

scorpio的博客 1095

23种设计模式——责任链模式(Chain of Responsibility Pattern)

本文介绍了23种经典设计模式之——责任链模式(Chain of Responsibility Pattern)的使用及说明

Meteors.的博客 885

设计模式之责任链模式【Chain Of Responsibility Pattern】

当客户端发出一个请求,有多个对象都有机会来处理这个请求,但是客户端不知道究竟谁会来处理他的请求时,这是就可以使用责任链模式来处理这种情况。 1、定义 使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。 2、使用场景 多个对象可以处理一个请求,但具体由哪个对象处理则在运行时动态决定。 在请求者不明确...

Rogera的博客 920

设计模式——责任链模式(Chain of Responsibility Pattern)+ Spring相关源码

每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

码鹿的记录 1014

设计模式:责任链模式(Chain of Responsibility Pattern)

责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。

TechNomad的博客 975

设计模式-12责任链模式Chain of Responsibility Pattern

责任链模式是一种行为设计模式,允许多个对象处理请求,避免请求发送者与接收者直接耦合。它将对象连成链,请求沿链传递直至被处理。适用于需要动态指定处理顺序、避免直接耦合的场景。结构包含处理者接口、抽象处理者和具体处理者。实现时,每个处理者决定是否能处理请求或传递给下一处理者。示例展示了采购审批流程,不同级别审批人根据金额限制处理请求,无法处理则转交上级。

d3y1`5 81_09 862

Java设计模式 十九 责任链模式 (Chain of Responsibility Pattern)

责任链模式通过将请求沿链传递,让多个对象有机会处理请求,避免了请求发送者与接收者的直接耦合。它使得对象的行为更加灵活,并且能够在不修改客户端代码的前提下,动态地改变处理流程。虽然责任链模式提供了更大的灵活性,但在链较长或处理较复杂时,可能导致处理效率降低,因此需要在适当的场景中使用。

空 1040

java设计模式---责任链模式(Chain of responsibility pattern)

java设计模式—责任链模式(Chain of responsibility pattern) 1. 概述 之前我们已经结束了创建型和结构型设计模式,接下来我们介绍行为型设计模式,行为型设计模式包含了11中,首先介绍的是责任链模式。该模式中包含了一些命令对象和一系列的处理对象,每一个对象都都保有对其下家的引用。如果我们将链中的每个节点看做是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从...

渔潭的博客 936

[设计模式] 责任链模式(Chain of Responsibility Pattern)

什么是责任链模式? 责任链模式是一种对象行为模式。顾名思义,责任链就是把承担不同责任的对象通过某种方式连接在一起形成一条链。当客户端把请求发送到这个责任链上的时候,本质上就是在链上不同的对象之间流转,直到链上的某个对象可以处理该请求,或者每个对象都处理该请求。 根据链上对象对请求的不同处理方式,责任链模式有两类: (1) 纯责任链模式 一个具体的处理者对象只能在两个行为中选择一个:要么承担全部责任,要么将责任推给下家。不允许出现某一个具体处理者对象在承担了一部分或者全部责任后,又将责任向下传递的情况。 一

asd13518662的博客 187
上一篇: 设计模式-策略模式
下一篇: 设计模式-迭代器模式
黄金时代的架构之路
博客等级 码龄12年 540粉丝 127原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值