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

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

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

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

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

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

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

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

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

kotlin 复制代码
// 抽象处理者
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)
}

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

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

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

kotlin 复制代码
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方法中实现日志记录的逻辑。

kotlin 复制代码
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中的拦截器链中。

kotlin 复制代码
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!😃😃

相关推荐
千里马学框架18 小时前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台18 小时前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone18 小时前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc19 小时前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo21 小时前
Kotlin 协程中的 Job 结构化并发与取消
android
sun00770021 小时前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼1 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone1 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen1 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone1 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui