• 设计模式之责任链模式


    责任链模式含义

    在阅读OkHttp源码的过程中,我发现他在处理拦截器的过程中非常巧妙,结合了责任链模式,将Request以链路的方式传递下去,再将Response以方向链路传递上去。

    责任链模式(Chain of Responsibility)使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

    实例

    通过模仿OkHttp写一个责任链模式,处理请求和响应。
    假设一个Request请求,需要经过Log、Header、Connect和Call四个流程,每个流程都会单独对Request进行处理,最终从流程的末端获取Response。
    在这里插入图片描述
    具体流程如上图所以,Chain作为链条,驱动着Request请求的开始,同时也是最终拿到Response的对象。

    • 实线部分为完整的一个责任链流程,Chain发起,经过Logger->Header->Connect->Call,等到Call处理完结果,再将结果方向传递上去,依次经过Call->Connect->Header->Logger->Chain。
    • 虚线部分为中途被某一个对象提前消费返回,比如在Header步骤出现异常,生成一个空的Response返回,那么请求流程就变为Chain->Logger->Header,返回流程则为Header->Logger->Chain;这就是责任链模式的魅力,链中任何一个对象都可以提前消费并返回,而且不影响链路的正常执行。

    代码

    定义Chain、Request和Response

    /**
     * [Chain]对象用来发起请求,并且接收最终的结果
     */
    class Chain(private val interceptorList: List<Interceptor>, private val index: Int, val request: Request) {
       
    
        /**
         * 依次调用链对象处理方法
         */
        fun process(request: Request): Response {
       
            // 同样使用index作为下标,用来依次调用链中对象
            val next = Chain(interceptorList, index = this.index + 1, request)
            val interceptor = interceptorList[index]
            return interceptor.intercept(next)
        }
    }
    
    /**
     * [Request]
     */
    class Request(var msg: String) {
       
    
        fun buildRequest(msg: String) = Request(msg)
    }
    
    /**
     * [Response]
     */
    class Response(val msg: String) {
       
        fun buildResponse(msg: String) = Response(msg)
    }
    
    
    • 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

    定义Interceptor基类和四个链对象

    /**
     * [Interceptor]对象用来处理链中对象的逻辑
     */
    interface Interceptor {
       
    
        fun intercept(chain: Chain): Response
    }
    
    class LoggerInterceptor : Interceptor {
       
        override fun intercept(chain: Chain): Response {
       
            val request = chain.request
            println("logger request: ${
         request.msg}")
            val response = chain.process(request.buildRequest("logger"))
            println("logger response: 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    C++动态规划算法的应用:得到 K 个半回文串的最少修改次数 原理源码测试用例
    FPGA CFGBVS 管脚接法
    信息学奥赛一本通:2034:【例5.1】反序输出
    C#二次开发BIMFACE系列67 File Management文件管理服务及应用场景
    Nginx搭配负载均衡和动静分离:构建高性能Web应用的完美组合
    ELK单机版部署踩坑及与Springboot整合
    苹果设计思维案例研究,困难期生存的关键
    力扣刷题记录167.1-----1356. 根据数字二进制下 1 的数目排序
    GSCoolink GSV9001 HDMI2to1 Video Processor
    Design patterns--观察者模式
  • 原文地址:https://blog.csdn.net/ChenYiRan123456/article/details/137110170