安卓常见设计模式10------责任链模式(Kotlin版)

1. W1 是什么,什么是责任链模式?​

  1. 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它用于将请求的发送者和接收者解耦,并将请求沿着一个处理链进行传递,直到有一个处理者能够处理该请求或者请求到达末尾
  2. 责任链模式允许多个对象都有机会处理请求,而不是将请求的发送者和接收者直接耦合在一起。

2. W2 为什么,为什么需要使用责任链模式,能给我们编码带来什么好处?​

  1. 解耦和灵活性:责任链模式将请求的发送者和接收者解耦,每个处理者只负责处理自己能够处理的请求,可以根据需要动态调整和扩展处理链。

  2. 可扩展性:可以方便地添加新的处理者到处理链中,不影响现有的处理者和客户端代码。

  3. 可维护性:责任链模式使得代码更易于理解和维护,每个处理者只关注自己的职责,使得代码结构清晰。

3. W3,如何使用?下面是代码示例:

假设有一个 Android 应用程序,用户可以通过不同的验证方式进行身份验证,包括指纹验证、面部识别和密码验证。我们可以使用责任链模式来实现这个验证过程:

// 抽象处理者
abstract class AuthenticationHandler {private var nextHandler: AuthenticationHandler? = nullfun setNext(handler: AuthenticationHandler) {nextHandler = handler}fun authenticate(request: AuthenticationRequest) {if (canHandle(request)) {handle(request)return} else if (nextHandler != null) {nextHandler?.authenticate(request)} else {println("无法验证身份")}}protected abstract fun canHandle(request: AuthenticationRequest): Booleanprotected abstract fun handle(request: AuthenticationRequest)
}// 指纹验证处理者
class FingerprintHandler : AuthenticationHandler() {override fun canHandle(request: AuthenticationRequest): Boolean {return request.method == AuthenticationMethod.FINGERPRINT}override fun handle(request: AuthenticationRequest) {println("进行指纹验证")// 进行指纹验证的具体逻辑}
}// 面部识别处理者
class FaceRecognitionHandler : AuthenticationHandler() {override fun canHandle(request: AuthenticationRequest): Boolean {return request.method == AuthenticationMethod.FACE_RECOGNITION}override fun handle(request: AuthenticationRequest) {println("进行面部识别")// 进行面部识别的具体逻辑}
}// 密码验证处理者
class PasswordHandler : AuthenticationHandler() {override fun canHandle(request: AuthenticationRequest): Boolean {return request.method == AuthenticationMethod.PASSWORD}override fun handle(request: AuthenticationRequest) {println("进行密码验证")// 进行密码验证的具体逻辑}
}// 身份验证请求
data class AuthenticationRequest(val method: AuthenticationMethod)// 身份验证方式枚举
enum class AuthenticationMethod {FINGERPRINT,FACE_RECOGNITION,PASSWORD
}// 客户端代码
fun main() {val fingerprintHandler = FingerprintHandler()val faceRecognitionHandler = FaceRecognitionHandler()val passwordHandler = PasswordHandler()// 构建处理链fingerprintHandler.setNext(faceRecognitionHandler)faceRecognitionHandler.setNext(passwordHandler)// 创建身份验证请求val request = AuthenticationRequest(AuthenticationMethod.FACE_RECOGNITION)// 发起身份验证请求fingerprintHandler.authenticate(request)
}

上面的示例中,身份验证沿着一个处理链进行传递,直到有一个处理者能够验证,则停止处理链的执行。如果需求需要走完整个处理链,否则就抛出异常的话,请参考下面的示例:

假设在一个电子商务平台上,当用户下单购买商品时,订单需要经过一系列的处理步骤,包括库存检查、价格计算、优惠券验证、支付处理等。

在这个场景下,也可以使用责任链模式来处理订单。每个处理步骤都可以看作是责任链中的一个处理者,它们按照一定的顺序链接在一起。当一个订单被创建后,它会依次经过责任链中的每个处理者,直到订单被完全处理。

interface OrderHandler {fun handleOrder(order: Order)
}class InventoryCheckHandler : OrderHandler {var nextHandler: OrderHandler? = nulloverride fun handleOrder(order: Order) {// 检查库存是否充足// 若库存不足,抛出异常或进行其他处理// 若库存充足,将订单传递给下一个处理者nextHandler?.handleOrder(order)}
}class PriceCalculationHandler : OrderHandler {var nextHandler: OrderHandler? = nulloverride fun handleOrder(order: Order) {// 计算订单的价格// 将价格计算结果存入订单对象// 将订单传递给下一个处理者nextHandler?.handleOrder(order)}
}class CouponValidationHandler : OrderHandler {var nextHandler: OrderHandler? = nulloverride fun handleOrder(order: Order) {// 验证订单中的优惠券是否有效// 若优惠券无效,抛出异常或进行其他处理// 若优惠券有效,将订单传递给下一个处理者nextHandler?.handleOrder(order)}
}class PaymentHandler : OrderHandler {override fun handleOrder(order: Order) {// 处理订单的支付操作// 更新订单状态等// 完成订单处理,不再传递给下一个处理者}
}class Order {// 订单的属性和方法
}class OrderProcessingChain {private val firstHandler: OrderHandlerinit {// 构建责任链// 设置责任链中的处理者顺序val inventoryCheckHandler = InventoryCheckHandler()val priceCalculationHandler = PriceCalculationHandler()val couponValidationHandler = CouponValidationHandler()val paymentHandler = PaymentHandler()inventoryCheckHandler.nextHandler = priceCalculationHandlerpriceCalculationHandler.nextHandler = couponValidationHandlercouponValidationHandler.nextHandler = paymentHandlerfirstHandler = inventoryCheckHandler}fun processOrder(order: Order) {// 将订单传递给责任链的第一个处理者firstHandler.handleOrder(order)}
}fun main() {val order = Order()val chain = OrderProcessingChain()chain.processOrder(order)
}

在OkHttp库中,okhttp3.Interceptor接口就使用了责任链模式,用于拦截和处理HTTP请求和响应。

Interceptor接口定义了一个方法intercept,该方法接收一个Chain对象作为参数,代表了整个拦截器链。Chain接口提供了对请求和响应的访问以及继续执行下一个拦截器的功能。

由于责任链模式的灵活性和可扩展性,所以当我们需要在OkHttp中添加自定义拦截器时(比如自定义日志拦截器),我们可以很容易地创建一个实现Interceptor接口的日志拦截器,并在其intercept方法中实现日志记录的逻辑。

class LoggingInterceptor : Interceptor {@Throws(IOException::class)override fun intercept(chain: Interceptor.Chain): Response {val request: Request = chain.request()// 记录请求信息val startTime = System.nanoTime()println("Sending request: ${request.url()}")val response: Responsetry {response = chain.proceed(request)} catch (e: IOException) {// 记录请求异常println("Request failed: ${e.message}")throw e}// 记录响应信息val endTime = System.nanoTime()val duration = endTime - startTimeprintln("Received response for ${request.url()} in ${duration / 1e6}ms")return response}
}

然后,将该自定义拦截器添加到OkHttpClient中的拦截器链中。

fun main() {val client = OkHttpClient.Builder().addInterceptor(LoggingInterceptor()).build()val request = Request.Builder().url("https://api.example.com").build()try {val response: Response = client.newCall(request).execute()// 处理响应} catch (e: IOException) {// 处理异常}
}

Thank you for your reading, best regards!😃😃

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

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

相关文章

Hive 知识点八股文记录 ——(二)优化

函数 UDF:用户定义函数 UDAF:用户定义聚集函数 UDTF:用户定义表生成函数 建表优化 分区建桶 创建表时指定分区字段 PARTITIONED BY (date string)指定分桶字段和数量 CLUSTERED BY (id) INTO 10 BUCKETS插入数据按分区、分桶字段插入 …

【数据结构】树与二叉树(八):二叉树的中序遍历(非递归算法NIO)

文章目录 5.2.1 二叉树二叉树性质引理5.1:二叉树中层数为i的结点至多有 2 i 2^i 2i个,其中 i ≥ 0 i \geq 0 i≥0。引理5.2:高度为k的二叉树中至多有 2 k 1 − 1 2^{k1}-1 2k1−1个结点,其中 k ≥ 0 k \geq 0 k≥0。引理5.3&…

【postgresql】CentOS7 安装pgAdmin 4

CentOS7 安装PostgreSQL Web管理工具pgAdmin 4。 pgAdmin 是世界上最先进的开源数据库 PostgreSQL 最受欢迎且功能丰富的开源管理和开发平台。 下载地址: pgadmin-4 download pgAdmin 4分为桌面版和服务器版。 我们这里部署服务器版本。 安装RPM包。 安装源 s…

现在学编程还能够月薪过万吗?

当我们谈到职业选择时,一项常受人关注的问题是,现在学编程还能月薪过万吗?这似乎是一个不断挂在年轻人嘴边的问题,尤其是在数字化时代,编程的需求越来越大。 所以今天让我们一起探讨这个问题,看看现实生活…

聊聊logback的ShutdownHook

序 本文主要研究一下logback的ShutdownHook ShutdownHook ch/qos/logback/core/hook/ShutdownHook.java /*** Interface describing a logback shutdown hook implementation* * author Mike Reinhold*/ public interface ShutdownHook extends Runnable, ContextAware { }…

汽车标定技术(九)--标定常量与#pragma的趣事

目录 1. 不添加#pragma语句 2. 添加#pragma语句 3. 标定量只给flash空间,不给ram指定空间 4. 总结 在之前不会使用overlay机制的时候,我们想要做汽车标定,标定常量编译出来的地址一般都应该是ram的地址,而且在链接文件中都会指…

6.5对称二叉树(LC101-E)

算法: 其实就是比较左右子树是否可以翻转 比较的时候: 比较外面的节点是否相等,如示例1中的节点3 比较里面的节点是否相等,如示例1中的节点4 基本思路是这样的,那怎么遍历呢? 二叉树的题一定要掌握到…

更安全的ssh协议与Gui图形化界面使用

目录 前言: 一.Gui图形化界面的使用 二.ssh协议 SSH的主要作用包括: 相比其他网络协议,SSH的优势包括: 三.idea集成Git 前言: 上一篇讲解了git的命令用法以及https协议,但是这个协议放在做团队项目的…

Git系列之Git集成开发工具及git扩展使用

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《Git实战开发》。🎯🎯 &a…

我的月光宝盒初体验失败了

哈哈哈,我爱docker, docker 使我自由!!! docker make me free! 菠萝菠萝蜜口号喊起来。 https://github.com/vivo/MoonBox/ windows上安装好了docker之后,docker-compose是自带的。 docker-compose -f docker-compo…

Springboot整合Jedis实现单机版或哨兵版可切换配置

Springboot整合Jedis实现单机版或哨兵版可切换配置 前言实现最后 前言 前文写到借助redis实现Shiro实现session限制登录数量踢人下线,本文就写一下Jedis的配置,可切换单机版和集群哨兵版,方便开发测试。 实现 很简单,直接上代码&…

王学岗visibility改变后调用onLayout()

自定义控件的时候发现了一个bug。 Button位移动画执行结束后我设置了一个不相关的TextView的可见性由gone变为visible.令人郁闷的是,只要我注释的地方放开。动画执行结束后button都会重新绘制在位移动画开始的位置。注释掉这段代码就正常。 经过分析后得知 View的Vi…

C# OpenCvSharp DNN HybridNets 同时处理车辆检测、可驾驶区域分割、车道线分割

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; using System.Numerics; using System.Text; using System.Windows.Forms;namespace OpenCvSharp_D…

城市内涝积水的原因有哪些?万宾科技内涝积水监测仪工作原理

一旦有暴雨预警出现多地便会立即响应,以防城市内涝问题出现。随着人口迁移,越来越多的人口涌入城市之中,为了完善城市基础设施建设,城市应急管理部门对内涝的监测越来越严格,在信息化时代,城市管理也趋向于…

G2406C是一款高效的直流-直流降压开关稳压器,能够提供高达1A输出电流。

G2406C 1.5MHz,1A高效降压DC-DC转换器 概述: G2406C是一款高效的直流-直流降压开关稳压器,能够提供高达1A输出电流。G2406C在2.7V至5.5V的宽范围输入电压下工作,使IC是低压电源转换的理想选择。在1.5MHz的固定频率下运行允许使用具有小电感…

【C++】异常 智能指针

C异常 & 智能指针 1.C异常1.1.异常的抛出与捕获1.2.异常体系1.3.异常安全与规范1.4.异常优缺点 2.智能指针2.1.RAII2.2.智能指针的使用及原理2.2.1.auto_ptr2.2.2.unique_ptr2.2.3.shared_ptr2.2.4.shared_ptr的循环引用问题 & weak_ptr 2.3.定制删除器 1.C异常 C异常…

百度智能云千帆大模型平台再升级,SDK版本开源发布!

SDK 前言一、SDK的优势二、千帆SDK:快速落地LLM应用三、如何快速上手千帆SDK1、SDK快速启动快速安装平台鉴权如何获取AK/SK以“Chat 对话”为调用示例 2. SDK进阶指引3. 通过Langchain接入千帆SDK为什么选择Langchain 开源社区 前言 百度智能云千帆大模型平台再次升…

Spring-Security权限实例

基于springBoot项目 引入依赖配置文件 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency> 快速上手 不连接数据库 1.创建用户实体类 Data AllArgsConstruct…

伦敦金冬令时开市时间怎样调整

在刚刚过去的一周&#xff0c;欧美的金融市场已经正式进入了冬令时&#xff0c;这对伦敦金市场的交易时间也产生了影响。由于美国于今年11月5日(星期日&#xff09;开始正式实施冬令时间&#xff0c;所以香港的伦敦金平台的交易时间也随之而有所调整。 从今年11月6日开始&#…

增强地理热图:Highcharts Maps v11.2.0 Crack

Highcharts Maps v11.2.0 添加了对地理热图插值的支持&#xff0c;允许您在类似温度图的图表的已知数据点之间添加估计值。 Highcharts Maps 提供了一种符合标准的方法&#xff0c;用于在基于 Web 的项目中创建逻辑示意图。它扩展了用户友好的 Highcharts JavaScript API&#…