责任链模式与lambda重构责任链模式
一、概念以及背景
责任链模式(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重构责任链模式相关推荐
- 责任链模式实践之Zuul责任链模式
责任链模式实践之Zuul责任链模式 一,什么是责任链模式 责任链(Chain of Responsibility)模式的定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对 ...
- 设计模式——行为型模式之责任链模式(简简单单入门责任链,理解I/O流消息怎么逐步传递处理以及服务器框架转发)
文章目录 前言 一.责任链模式定义 二.责任链模式结构 三.责任链高级应用 四.责任链模式优缺点 设计模式系列文章 结尾 前言 作者更有一系列设计模式文章(还在持续更新),图例丰富,少量代码,适合入门 ...
- 【设计模式系列19】状态模式原理分析及其和策略模式,责任链模式的区别
状态模式原理分析 设计模式系列总览 前言 什么是状态模式 状态模式示例 状态模式角色 状态模式与责任链模式 状态模式与策略模式 状态模式应用场景 状态模式优缺点 总结 设计模式系列总览 设计模式 飞机 ...
- 图解Java设计模式学习笔记——行为型模式(模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式)
一.模板方法模式(模板模式)--钩子方法 1.需求-豆浆制作问题 编写制作豆浆的程序,说明如下: 制作豆浆的流程选材-->添加配料-->浸泡-->放到豆浆机打碎. 通过添加不同的配料 ...
- java23中设计模式——行为模式——Chain of Responsibility(职责链)
2019独角兽企业重金招聘Python工程师标准>>> 角色 抽象处理者角色(Handler):定义出一个处理请求的接口.如果需要,接口可以定义 出一个方法以设定和返回对下家的引用. ...
- 区块链技术背景下数字音频商业模式变革的逻辑 - 基于云听、喜马拉雅FM和CastBox的对比分析
本文经过<传媒>杂志老师的授权.2022-08-24 ,我在微信公众号 乐生活与爱IT Plus上发表了原创文章<观念即商品.传播即分销.互动即迭代 |元宇宙和新媒体>,并提出 ...
- WKA去中心化交易,重构区块链价值网络
随着互联网技术的不断成熟与发展,越来越多的人选择线上交易.通证化是公司体制的变革,是未来各类机构的重要组织形态和机会,是可以将公司用户与公司权益的分配主体真正统一起来的经济模式.于是,数字资产安全与快 ...
- 澳门W.B.C开启世界区块链“峰会+嘉年华+学院+全球行”新模式
2018年4月23日至25日,第一届世界区块链大会在中国澳门举行,百位区块链大咖莅临现场,千名嘉宾.明星嘉年华盛大开启,万人峰会主会场分会场场场爆满. 大会以"技术重构世界"为主题 ...
- 长安链ChainMaker基于公钥用户标识的身份模式介绍
身份权限控制简介 在区块链中,身份权限控制是非常重要的一个环节.区块链技术在应用过程中,要面对各种不同的场景,而很多场景的区别,本质就是身份权限控制强弱的区别.例如,利用区块链技术的以太坊项目,身份权 ...
最新文章
- c++ 进程快照_如何在 Linux 中找出内存消耗最大的进程
- struts.properties属性解释
- Python客户端syn连接
- Matlab--绘图及坐标轴命令使用示例
- FlashDevelop 3.0.0 Beta2 released
- 优化MyBatis配置文件中的配置
- 如何使Session永不过期
- 人工智能语料库技术是什么?来看科普!
- 虚拟机桥接模式下配置静态IP
- php 导出图片到excel,从PHP导出图片excel的方法
- 证券交易系统搭建的架构方案
- 阿里 P7 前端高级工程师,都需要掌握哪些技术栈?
- 一张纸的厚度为0.08mm,对折多少次能达到或超过珠穆朗玛峰的高度(8848.13米)
- 全栈式PHP集成环境-laragon(二) 配置、使用
- 70年代生人的80年代
- cpu是几核的怎么查看
- Blender 使骨骼旋转方向一致
- python是一种语言吗-python语言是非开源语言吗
- YOLO系列目标检测算法-YOLOv7
- 月饼大战白热化,保险公司也来Battle了!