• 安卓常见设计模式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? = 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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

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

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

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

    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)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    在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
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    然后,将该自定义拦截器添加到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) {
            // 处理异常
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Thank you for your reading, best regards!😃😃

  • 相关阅读:
    侃车库文化,蕴含着无限潜能?
    当Serverless遇到Regionless:现状与挑战
    Redis6:NoSQL数据库概述(特点)、行式、列式存储数据库、图关系型数据库
    html5-drag和drop拖拽
    Java——迷你图书管理器(JDBC+MySQL+Apache DBUtils)
    分布式ID系统设计(2)
    MYSQL | 数据库到底是怎么来的?
    【C语言】指针作为参数传值常见问题
    java基于微信小程序的在线学习考试系统 uniapp 小程序
    线性代数的本质(三)
  • 原文地址:https://blog.csdn.net/qq_42751010/article/details/134310218