一、概念以及背景

责任链模式(Chain of Responsibility Pattern):责任链模式是一种创建处理对象序列(比如操作序列)的通用方案。一个处理对象可能需要在完成一些工作之后,将结果传递给另一个对象,这个对象接着做一些工作,再转交给下一个处理对象,以此类推。

简而言之,待处理的对象,需要经过好几个步骤的处理,形成一条链,一个步骤处理完之后,接着往下一个步骤继续处理。

本文涉及的代码在github上,点击 链接 可查看源码。

本文会用两种方式来实现责任链模式,第二种是用lambda表达式的方式来实现,参数行为化的方式实现。

本文所使用的场景如下:处理一封信,首先对会信的头部进行处理,然后会检查这份信的拼写有无错误,有的话把错误的单词修改过来,最后会对信的结尾进行处理。这样一来处理一封信就形成了一条链,先处理……,再处理……,最后处理……。

二、责任链模式

基于上面提到的场景,UML类图如下,责任链模式之所以能形成链,其核心是有一个抽象处理类,该抽象处理类会有一个字段(抽象处理者)被用来记录后续对象,即记录执行处理某个步骤的对象。然后该抽象处理类还有一个抽象方法,即handleWork抽象方法,每个处理步骤(链节点)都会实现该抽象方法,作为该步骤的处理逻辑,当然处理完之后还需要丢给下一个链节点处理。

  • Handler抽象类,即抽象处理类,含有一个字段是抽象处理者successor,当然也有setSuccessor方法,用来设置下一个处理者,即本步骤/链节点处理完之后,传递给下一个处理者继续处理。handleWork抽象方法提供了实现不同的处理步骤,有不同的处理逻辑,这里的handle方法也起到了不少的作用,形成链,本链节点handleWork之后,判断自身是否还拥有下一处理者,有的话,下一处理者继续进行handle->handleWork直到处理结束,无处理者。
public abstract class Handler {protected Handler successor;public void setSuccessor(Handler successor) {this.successor = successor;}abstract protected String handleWork(String input);public String handle(String input) {//本节点处理完之后返回下一节点String nextNode = handleWork(input);if (successor != null) {return successor.handle(nextNode);}return nextNode;}
}
  • AddHeaderHandler类,信的头部处理器
public class AddHeaderHandler extends Handler{@Overrideprotected String handleWork(String input) {return  "From Raoul, Mario and Alan: " + input;}
}
  • CheckSpellHandler类,检查信的拼写
public class CheckSpellHandler extends Handler{@Overrideprotected String handleWork(String input) {return input.replaceAll("labda", "lambda");}
}
  • AddFooterHandler类,信的结尾处理器
public class AddFooterHandler extends Handler{@Overrideprotected String handleWork(String input) {return  input + " Kind regards";}
}
public class ChainMain {public static void main(String[] args) {AddHeaderHandler addHeaderHandler = new AddHeaderHandler();CheckSpellHandler checkSpellHandler = new CheckSpellHandler();AddFooterHandler addFooterHandler = new AddFooterHandler();addHeaderHandler.setSuccessor(checkSpellHandler);checkSpellHandler.setSuccessor(addFooterHandler);String test = addHeaderHandler.handle("labda");System.out.println(test);}
}

最后控制台输出这封处理过的信:

From Raoul, Mario and Alan: lambda Kind regards

三、责任链模式,行为参数化,lambda方式重构

这里用了Java8的Function<T,R>函数式接口,方法apply输入T类型参数,返回R类型,T,R都是String类型,符合我们处理信件,输入和输出都是String类型。因为我们的核心在于处理信件的逻辑,故这里结合Java8函数式接口,把行为参数化,实现了处理信件的处理逻辑。

  • Function<T,R>
@FunctionalInterface
public interface Function<T, R> {R apply(T t);
}
  • LambdaHandler
public class LambdaHandler {public static Function<String, String> addHeaderHandler() {return (input) -> "From Raoul, Mario and Alan: " + input;}public static Function<String, String> checkSpellHandler() {return (input) -> input.replaceAll("labda", "lambda");}public static Function<String, String> addFooterHandler() {return (input) -> input + " Kind regards";}
}
  • ChainMain
public class ChainMain {public static void main(String[] args) {Function<String, String> addHeaderHandler = LambdaHandler.addHeaderHandler();Function<String, String> checkSpellHandler = LambdaHandler.checkSpellHandler();Function<String, String> addFooterHandler = LambdaHandler.addFooterHandler();String test = addHeaderHandler.andThen(checkSpellHandler).andThen(addFooterHandler).apply("labda");System.out.println(test);}
}
  • 最后控制台输出这封处理过的信:
From Raoul, Mario and Alan: lambda Kind regards

起核心作用的是Function<T, R>接口的默认方法andThen,除了内置函数式接口Function<T, R>有andThen默认方法,Consumer等内置函数式接口也是提供andThen默认方法的,大部分是能满足我们的需求的。
我们可以看到,andThen方法的方法参数也是一个跟自身相同的函数式接口Function<T,R>,只不过这里的泛型有下界通配符和上界通配符Function<? super R, ? extends V> after,当然我们可以暂不用细究这个,因为我们实现的接口都是入参和返回结果都是String类型。
Objects.requireNonNull(after); 首先判断传入的参数不能为空,毕竟这是下一个处理步骤的实现处理逻辑,关键是**(T t) -> after.apply(apply(t));** 这句代码起了作用,这里分为两步,第一步是先执行自身的apply(t) 方法,即在当前步骤,先对节点进行处理,然后返回处理结果,接着是对节点(本步骤的处理结果)进行下一步的处理,即 after.apply(apply(t))

@FunctionalInterface
public interface Function<T, R> {default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {Objects.requireNonNull(after);return (T t) -> after.apply(apply(t));}
}

当然节点的最后一个处理步骤,我们需要在最后返回的Function<T,R>在执行一次apply,调用最后一个处理步骤的实现方法,即


String test = addHeaderHandler.andThen(checkSpellHandler).andThen(addFooterHandler).apply("labda");

本文如有不足之处,请指正或者提出好的建议。◕‿◕。谢谢。

参考资料:《Java8实战》

责任链模式与lambda重构责任链模式相关推荐

  1. 责任链模式实践之Zuul责任链模式

    责任链模式实践之Zuul责任链模式 一,什么是责任链模式 责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对 ...

  2. 设计模式——行为型模式之责任链模式(简简单单入门责任链,理解I/O流消息怎么逐步传递处理以及服务器框架转发)

    文章目录 前言 一.责任链模式定义 二.责任链模式结构 三.责任链高级应用 四.责任链模式优缺点 设计模式系列文章 结尾 前言 作者更有一系列设计模式文章(还在持续更新),图例丰富,少量代码,适合入门 ...

  3. 【设计模式系列19】状态模式原理分析及其和策略模式,责任链模式的区别

    状态模式原理分析 设计模式系列总览 前言 什么是状态模式 状态模式示例 状态模式角色 状态模式与责任链模式 状态模式与策略模式 状态模式应用场景 状态模式优缺点 总结 设计模式系列总览 设计模式 飞机 ...

  4. 图解Java设计模式学习笔记——行为型模式(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式)

    一.模板方法模式(模板模式)--钩子方法 1.需求-豆浆制作问题 编写制作豆浆的程序,说明如下: 制作豆浆的流程选材-->添加配料-->浸泡-->放到豆浆机打碎. 通过添加不同的配料 ...

  5. java23中设计模式——行为模式——Chain of Responsibility(职责链)

    2019独角兽企业重金招聘Python工程师标准>>> 角色 抽象处理者角色(Handler):定义出一个处理请求的接口.如果需要,接口可以定义 出一个方法以设定和返回对下家的引用. ...

  6. 区块链技术背景下数字音频商业模式变革的逻辑 - 基于云听、喜马拉雅FM和CastBox的对比分析

    本文经过<传媒>杂志老师的授权.2022-08-24 ,我在微信公众号 乐生活与爱IT Plus上发表了原创文章<观念即商品.传播即分销.互动即迭代 |元宇宙和新媒体>,并提出 ...

  7. WKA去中心化交易,重构区块链价值网络

    随着互联网技术的不断成熟与发展,越来越多的人选择线上交易.通证化是公司体制的变革,是未来各类机构的重要组织形态和机会,是可以将公司用户与公司权益的分配主体真正统一起来的经济模式.于是,数字资产安全与快 ...

  8. 澳门W.B.C开启世界区块链“峰会+嘉年华+学院+全球行”新模式

    2018年4月23日至25日,第一届世界区块链大会在中国澳门举行,百位区块链大咖莅临现场,千名嘉宾.明星嘉年华盛大开启,万人峰会主会场分会场场场爆满. 大会以"技术重构世界"为主题 ...

  9. 长安链ChainMaker基于公钥用户标识的身份模式介绍

    身份权限控制简介 在区块链中,身份权限控制是非常重要的一个环节.区块链技术在应用过程中,要面对各种不同的场景,而很多场景的区别,本质就是身份权限控制强弱的区别.例如,利用区块链技术的以太坊项目,身份权 ...

最新文章

  1. c++ 进程快照_如何在 Linux 中找出内存消耗最大的进程
  2. struts.properties属性解释
  3. Python客户端syn连接
  4. Matlab--绘图及坐标轴命令使用示例
  5. FlashDevelop 3.0.0 Beta2 released
  6. 优化MyBatis配置文件中的配置
  7. 如何使Session永不过期
  8. 人工智能语料库技术是什么?来看科普!
  9. 虚拟机桥接模式下配置静态IP
  10. php 导出图片到excel,从PHP导出图片excel的方法
  11. 证券交易系统搭建的架构方案
  12. 阿里 P7 前端高级工程师,都需要掌握哪些技术栈?
  13. 一张纸的厚度为0.08mm,对折多少次能达到或超过珠穆朗玛峰的高度(8848.13米)
  14. 全栈式PHP集成环境-laragon(二) 配置、使用
  15. 70年代生人的80年代
  16. cpu是几核的怎么查看
  17. Blender 使骨骼旋转方向一致
  18. python是一种语言吗-python语言是非开源语言吗
  19. YOLO系列目标检测算法-YOLOv7
  20. 月饼大战白热化,保险公司也来Battle了!

热门文章

  1. C语言格式化输入和输出; Format格式化
  2. oracle删除大量数据
  3. 数字藏品叠加元宇宙热潮,数字艺术会迎来怎样的发展
  4. Maltego 版本类型重新选择
  5. 吴恩达---机器学习笔记
  6. MFC连接sqlite3数据库
  7. 如何写好JAVA代码
  8. MATLAB绘制圆、椭圆、矩形等基本平面图形
  9. 你拥有的最宝贵的财富是什么?(通向财富自由学习笔记三)
  10. comp3411辅导assignment2