Kotlin~责任链模式

概念

允许多个对象按顺序处理请求或任务。

角色介绍

  • Handler: 处理器接口,提供设置后继者(可选)
  • ConcreteHandler:具体处理器,处理请求

UML

责任链

代码实现

atm

比如ATM机吐钱就可以使用责任链实现。

class PartialFunction<in P1, out R>(private val definetAt: (P1) -> Boolean,private val f: (P1) -> R
) : (P1) -> R {override fun invoke(p1: P1): R {if (definetAt(p1)) {return f(p1)} else {throw IllegalAccessException()}}fun isDefinedAt(p1: P1) = definetAt(p1)
}/*** orElse 方法种可以传入另一个 PartialFunction 类对象 that,它也就是责任链模式中的后继者* infix 关键字让 orElse 成为一个中缀函数,从而让责任链调用的语法变得更加直观*/
infix fun <P1, R> PartialFunction<P1, R>.orElse(that: PartialFunction<P1, R>): PartialFunction<P1, R> {return PartialFunction({this.isDefinedAt(it) || that.isDefinedAt(it)}) {when {this.isDefinedAt(it) -> this(it)else -> that(it)}}
}

什么是偏函数?

在Scala中偏函数使用PartialFuncation构建只处理输入参数的部分分支的函数,也就是带判断条件的函数。在python中作用就是把一个函数的某些参数给固定住(也就是设置成默认值),返回一个新的函数。这样调用的时候就会比较简单。

data class Current(var cash: Int, val message: MutableList<String>)val RMB_5 = run {val definetAt: (Current) -> Boolean = { it.cash >= 5 }val handler: (Current) -> Unit = {println("处理5元")val num = it.cash / 5it.cash = it.cash % 5it.message.add("5元 * $num")}PartialFunction(definetAt, handler)
}
val RMB_10 = run {val definetAt: (Current) -> Boolean = { it.cash >= 10 }val handler: (Current) -> Unit = {println("处理10元")val num = it.cash / 10it.cash = it.cash % 10it.message.add("10元 * $num")}PartialFunction(definetAt, handler)
}
val RMB_20 = run {val definetAt: (Current) -> Boolean = { it.cash >= 20 }val handler: (Current) -> Unit = {println("处理20元")val num = it.cash / 20it.cash = it.cash % 20it.message.add("20元 * $num")}PartialFunction(definetAt, handler)
}
val RMB_50 = run {val definetAt: (Current) -> Boolean = { it.cash >= 50 }val handler: (Current) -> Unit = {println("处理50元")val num = it.cash / 50it.cash = it.cash % 50it.message.add("50元 * $num")}PartialFunction(definetAt, handler)
}
val RMB_100 = run {val definetAt: (Current) -> Boolean = { it.cash >= 100 }val handler: (Current) -> Unit = {println("处理100元")val num = it.cash / 100it.cash = it.cash % 100it.message.add("100元 * $num")}PartialFunction(definetAt, handler)
}fun ATMMachine(atmChain: PartialFunction<Current, Unit>, cash: Current): Int {atmChain(cash)return if (cash.cash < 5) {if (cash.cash > 0) {cash.message.add("1元 * ${cash.cash}")}0} else {ATMMachine(atmChain, cash)}
}fun main(args: Array<String>) {val atmChain = RMB_100 orElse RMB_50 orElse RMB_20 orElse RMB_10 orElse RMB_5val user = Current(1084, ArrayList<String>())ATMMachine(atmChain, user)for (s in user.message) {println(s)}
}

优缺点

优点

  • 分离发送着和接收者
  • 链中的灵活性
  • 易于扩展和维护

缺点

  • 无法保证处理请求
  • 性能开销较大
  • 调试复杂度高

应用场景

有多个对象可以处理请求,动态添加、删除修改请求处理器。

  • 中间件
  • GUI时间处理器
  • 异常处理
  • 工作流

总结

责任链平时在业务开发中使用较少,像OkHttp网络请求框架就使用了责任链模式。它里面定义了主要以下几个拦截器:

  • RetryAndFollowUpInterceptor : 负责失败重试和重定向

  • BridgeIntezceptor : 负责处理http 通用请求头和返回头,Cookie

  • CacheInterceptor : 负责处理缓存

  • ConnectInterceptor : 开启和服务器的连接

  • networkInterceptors : 用户定义的网络拦截器,权限更高,更接近底层,一般不需要关注

  • CallServerInterceptor : 实现网络请求

具体可以参考OKHTTP源码解析

  • OKHttp源码解析(二)-责任链_okhttp责任链_夏屿_的博客
  • Okhttp之责任链

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/19442.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

POLARDB IMCI 白皮书 云原生HTAP 数据库系统 一 列式数据是如何存储与处理的

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请联系 liuaustin3 &#xff0c;在新加的朋友会分到2群&#xff08;共…

无聊猿惨遭亏本甩卖 “贵族”持有人沦为“大冤种

被称为NFT贵族的无聊猿&#xff08;BAYC&#xff09;正在进行挥泪大甩卖&#xff0c;歌手黄立成等持有者们近期不断抛售BAYC NFT&#xff0c;导致该系列NFT地板价一度跌至30 ETH&#xff08;约5.7万美元&#xff09;以下。 一年多以前&#xff0c;BAYC还是时尚界的宠儿&#x…

JavaCV实现byte[]转RTMP流

需求&#xff1a;通过私有的api我可以不断收到byte[]形式的视频数据&#xff0c;现在我需要处理这些数据&#xff0c;最终推送出RTMP流。 实现&#xff1a;通过管道流将不断收到的byte[]视频数据转化为输入流然后提供给JavaCV的FFmpegFrameGrabber使用&#xff0c;然后通过FFmp…

96、基于STM32单片机的温湿度DHT11 烟雾火灾报警器蓝牙物联网APP远程控制设计(程序+原理图+任务书+参考论文+开题报告+流程图+元器件清单等)

单片机及温湿度、烟雾传感器是烟雾报警器系统的两大核心。单片机好比一个桥梁&#xff0c;联系着传感器和报警电路设备。近几年来&#xff0c;单片机已逐步深入应用到工农业生产各部门及人们生活的各个方面。各种类型的单片机也根据社会的需求而开发出来。单片机是器件级计算机…

机器人xacro文件转换成urdf文件方法,并在rviz可视化

一、进入工作空间&#xff0c;source一下 cd cat_ws source devel/setup.bash二、进入xacro所在的文件夹&#xff0c;完成xacro文件到urdf文件的转换 cd src/kinova-ros/kinova_description/urdf/然后执行下面命令 rosrun xacro xacro.py two_arm_robot_example_standalone.…

华为路由器如何通过Console口进行基本配置

华为HCIA试听课程&#xff1a;不会传输层协议&#xff0c;HCIA都考不过https://mp.weixin.qq.com/s/oKAL8GvdrcHEb5O_8bEZZQ 思科CCNA试听课程&#xff1a;适合初学者&#xff1a;VLAN原理与配置https://mp.weixin.qq.com/s/toIJg1EVFImalrwzbTONTQ 组网图形 组网需求 通过Cons…

设计模式之责任链模式

文章目录 1、基本介绍2、包含角色3、场景推导4、责任链模式的优缺点5、使用场景 1、基本介绍 王二狗本来是干Android开发的&#xff0c;最近公司想让他把IOS的活也干了&#xff0c;但是Windows笔记本不能开发IOS&#xff0c;所以二狗提出买一台Mac笔记本电脑。这花钱的事需要领…

css animation 鼠标移入暂停会抖动

如图 实现一个赞助商横向滚动列表墙&#xff0c; 上下两排向右滚动&#xff0c;中间向左滚动&#xff0c;鼠标移入暂停当前行。 实现&#xff1a; // 使用animation.moving {animation: move 20s linear infinite; }keyframes move {0% {}100% {transform: translateX(-50%);…

node版本控制工具nvm使用笔记

由于不同的项目所需要的node环境不同&#xff0c;所以在运行支持node 12或者node 16版本的项目时卸载安装不同版本的node非常麻烦&#xff0c;恰巧公司有一个热心的同事告诉我可以使用nvm来进行版本控制&#xff0c;我使用了之后发现确实好用&#xff0c;写一篇笔记记录一下。 …

C#内存不够解决方法

今天在使用C#程序的时候&#xff0c;出现了下图的问题&#xff1a; 注意下图中我用红框标出的位置&#xff0c;实际是一个三维数组。 但是出现这个问题和三维数组没有关系。 他是提示内存不足。 百度了一下&#xff0c;C#在生成的过程中如果是生成对应的32位系统&#xff0c…

【优选算法】—— 滑动窗口类问题

本期&#xff0c;我给大家带来的是关于滑动窗口类算法的介绍&#xff0c;并通过具体的题目帮助大家思考理解。 目录 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;题目讲解 1、难度&#xff1a;medium 1️⃣长度最小的子数组 2️⃣找到字符串中所有字⺟…

“坏邻居”导致的kafka生产者TPS下降原因排查

背景&#xff1a; 今天测试了两种不同的场景下kafka producer的tps性能数据&#xff0c;两种场景下都是使用3个线程&#xff0c;每个线程都是对应一个kafka producer&#xff0c;测试发送到kafka集群的消息的量&#xff0c;两个场景的区别是场景A只发送kafka消息&#xff0c;场…