【设计模式笔记】责任链/职责链模式

一、介绍

责任链模式是一种对象的行为模式。在责任链模式里,为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。

实现方式:

  1. 使用链表的方式进行串联,将多个handler串联起来;
  2. 使用list方式,循环执行list中的每个handler;

优点:

  1. 降低耦合性,发送者,发送处理者,接收者三者进行了解耦;
  2. 简化对象,对象不需要知道链的结构;
  3. 增强了灵活性,使得增加和删除请求变得容易;

缺点:

  1. 不能保证请求一定被接收;
  2. 可能不容易观察运行时的特征,有碍于除错;

二、使用

1. okhttp中的拦截链- list实现

okhttp中的interceptorChain的调用使用list存放interceptor,并通过递归的方式进行调用;

入口:

RealCall中的getResponseWithInterceptorChain()方法中创建InterceptorChain,然后调用chain.proceed(request: Request)开启责任链;

类图:
在这里插入图片描述

其中RealInterceptorChain继承Interceptor中的Chain,Chain接口可以携带实现的Interceptor所需要的相应内容;

RealInterceptorChain $proceed(request: Request)开启责任链模式:

@Throws(IOException::class)
override fun proceed(request: Request): Response {
    ... 
  // Call the next interceptor in the chain.
  // 浅拷贝一个RealIntercepterChain,主要目的将当前index向后一一位
  val next = copy(index = index + 1, request = request)
  // 获取当前index的Intercepter
  val interceptor = interceptors[index]

 // 执行当前Intercepter的intercepter(chain: Chain)方法,并传入之前浅拷贝的Chain;
  @Suppress("USELESS_ELVIS")
  val response = interceptor.intercept(next) ?: throw NullPointerException(
      "interceptor $interceptor returned null")
  return response
}

当初始化时,index=0,interceptors[0]为MyAppInterceptor, 以okhttp给出的例子来作为MyAppInterceptor;

MyAppinterceptor是okhttp给出的Application Interceptor,和Network Interceptor的最大区别来自于位置不同,所能够获取的request和response的不同;

class MyAppInterceptor: Interceptor{
    override fun intercept(chain: Interceptor.Chain): Response {
        // do something
        // 此时传入的Chain中的index为list中下一个interceptor的索引;
        // 此时直接继续调用RealInterceptorChain$process()直到CallServerInterceptor $intercept(chain: Interceptor.Chain);
        return chain.proceed(chain.request())
    }
}

最后到CallServerInterceptor i n t e r c e p t ( c h a i n : I n t e r c e p t o r . C h a i n ) , 不 再 调 用 R e a l I n t e r c e p t o r C h a i n intercept(chain: Interceptor.Chain),不再调用RealInterceptorChain intercept(chain:Interceptor.Chain)RealInterceptorChainprocess(),直接返回response;

class CallServerInterceptor(private val forWebSocket: Boolean) : Interceptor {

  @Throws(IOException::class)
  override fun intercept(chain: Interceptor.Chain): Response {
    // do something ... 
    var response = responseBuilder
        .request(request)
        .handshake(exchange.connection.handshake())
        .sentRequestAtMillis(sentRequestMillis)
        .receivedResponseAtMillis(System.currentTimeMillis())
        .build()
    // do something ... 
    return response
  }
}

kotlin使用小技巧:

// interceptor中增加invoke函数好,则可以直接使用lambda方法初始化;
  companion object {
    /**
     * Constructs an interceptor for a lambda. This compact syntax is most useful for inline
     * interceptors.
     *
     * ```
     * val interceptor = Interceptor { chain: Interceptor.Chain ->
     *     chain.proceed(chain.request())
     * }
     * ```
     */
    inline operator fun invoke(crossinline block: (chain: Chain) -> Response): Interceptor =
      Interceptor { block(it) }
  }

2. 链表实现;

具体实现方法如下所示:

public class FilterChain {
    Filter head = null;
    
    public void addFilter(Filter filter) {
        Filter curr = head;
        while (curr != null && curr.nextFilter != null) {
            curr = curr.nextFilter;
        }
        if (curr == null) curr = filter; 
        else curr.nextFilter = filter;
    }
    
    public void execute() {
        head.process();
    }
}

FilterChain保留了一个单向链表的起始点,每次增加需要遍历当前链表找到最后结点插入数据;

public abstract class Filter {
    Filter nextFilter;

    void process() {
        if (nextFilter == null) return;
        nextFilter.process();
    }
}

引用:
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值