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

news/2024/5/19 14:24:47 标签: android, 设计模式, 责任链模式

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

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

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

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

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

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

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

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

// 抽象处理者
abstract class AuthenticationHandler {
    private var nextHandler: AuthenticationHandler? = null

    fun 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): Boolean
    protected 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? = null

    override fun handleOrder(order: Order) {
        // 检查库存是否充足
        // 若库存不足,抛出异常或进行其他处理
        // 若库存充足,将订单传递给下一个处理者
        nextHandler?.handleOrder(order)
    }
}

class PriceCalculationHandler : OrderHandler {
    var nextHandler: OrderHandler? = null

    override fun handleOrder(order: Order) {
        // 计算订单的价格
        // 将价格计算结果存入订单对象
        // 将订单传递给下一个处理者
        nextHandler?.handleOrder(order)
    }
}

class CouponValidationHandler : OrderHandler {
    var nextHandler: OrderHandler? = null

    override fun handleOrder(order: Order) {
        // 验证订单中的优惠券是否有效
        // 若优惠券无效,抛出异常或进行其他处理
        // 若优惠券有效,将订单传递给下一个处理者
        nextHandler?.handleOrder(order)
    }
}

class PaymentHandler : OrderHandler {
    override fun handleOrder(order: Order) {
        // 处理订单的支付操作
        // 更新订单状态等
        // 完成订单处理,不再传递给下一个处理者
    }
}

class Order {
    // 订单的属性和方法
}

class OrderProcessingChain {
    private val firstHandler: OrderHandler

    init {
        // 构建责任链
        // 设置责任链中的处理者顺序
        val inventoryCheckHandler = InventoryCheckHandler()
        val priceCalculationHandler = PriceCalculationHandler()
        val couponValidationHandler = CouponValidationHandler()
        val paymentHandler = PaymentHandler()

        inventoryCheckHandler.nextHandler = priceCalculationHandler
        priceCalculationHandler.nextHandler = couponValidationHandler
        couponValidationHandler.nextHandler = paymentHandler

        firstHandler = 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: Response
        try {
            response = chain.proceed(request)
        } catch (e: IOException) {
            // 记录请求异常
            println("Request failed: ${e.message}")
            throw e
        }

        // 记录响应信息
        val endTime = System.nanoTime()
        val duration = endTime - startTime
        println("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.niftyadmin.cn/n/5166602.html

相关文章

竞赛选题 深度学习猫狗分类 - python opencv cnn

文章目录 0 前言1 课题背景2 使用CNN进行猫狗分类3 数据集处理4 神经网络的编写5 Tensorflow计算图的构建6 模型的训练和测试7 预测效果8 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习猫狗分类 ** 该项目较为新颖&a…

postgresql字段长度修改和数据重写

1 创建表查询日志 #创建表 postgres# create table t(id numeric(5)); CREATE TABLE postgres# select t::regclass::oid;oid -------50032 (1 row)#查看wal日志 [pg13sdw2 pg_wal]$ pg_waldump 0000000100000006000000A2 rmgr: Standby len (rec/tot): 50/ 50, …

【CAN总线】从数字设计的角度分析CAN协议1—CAN概述

文章目录 1.CAN是什么2.CAN总线特点3.CAN协议的基本概念4.CAN总线电平(1)ISO标准化的CAN协议(2)物理层的电平(3)总线拓扑图5.参考文献1.CAN是什么 CAN(Controller Area Network):串行通信总线,异步半双工通信。 在当前的汽车产业中,出于对安全性、舒适性、方便性、…

二十三种设计模式全面解析-组合模式与装饰器模式的结合:实现动态功能扩展

在前文中,我们介绍了组合模式的基本原理和应用,以及它在构建对象结构中的价值和潜力。然而,组合模式的魅力远不止于此。在本文中,我们将继续探索组合模式的进阶应用,并展示它与其他设计模式的结合使用,以构…

centos配置docker环境

CentOS系统更换软件安装源 yum默认链接的还是国外的镜像,速度相对不理想,配置成国内的镜像会快很多,这里以阿里镜像为例进行配置: 首先进行更新: yum updatebase源 第一步:备份你的原镜像文件,以免出错后…

关于Android Studio中开发Flutter配置

配置系统环境变量:path下 ,flutter的bin目录下 File->Settings->Languages&Frameworks->FlutterFile->Settings->Languages&Frameworks->DartFile->Settings->Languages&Frameworks->Android SDK 确认是…

Html 引入element UI + vue3 报错Failed to resolve component: el-button

问题&#xff1a;Html 引入element UI vue3 &#xff0c;el-button效果不出来 <!DOCTYPE html> <html> <head><meta charset"UTF-8"><!-- import Vue before Element --> <!-- <script src"https://unpkg.com/vue2/dist…

如何在Linux上部署1Panel运维管理面板并远程访问内网进行操作

文章目录 前言1. Linux 安装1Panel2. 安装cpolar内网穿透3. 配置1Panel公网访问地址4. 公网远程访问1Panel管理界面5. 固定1Panel公网地址 前言 1Panel 是一个现代化、开源的 Linux 服务器运维管理面板。高效管理,通过 Web 端轻松管理 Linux 服务器&#xff0c;包括主机监控、…