有人说Okhttp是责任链模式,那么能不能麻烦您给我讲一下它的责任链是怎么设计的?和常规责任链——无限循环链表相比有什么区别?责任链的优缺点在何处?
回答不了吧!这是本文要解决的一系列问题。
数据结构
一个List是拦截器集合
同时还有一个类,叫做Chain,每一个Chain都有一个对应的index。
一开始是Chain-0。
然后Chain-0.proceed,在执行这个方法的时候,生成了Chain-1,然后取出了第0个拦截器,执行
intercept-0.intercept,拦截器内部可以决定是直接返回response,还是拿着已生成的Chain-1.proceed继续执行。
听起来是不是很绕?但是事实就是如此。
简单梳理一下就是:
一个拦截器在执行任务的时候,可以直接返回response,也可以继续执行chain.proceed,这里面也就是拿到了下一个拦截器,然后继续执行。
我会怎么优化它
其他它更像是一种策略模式+责任链模式。它已经做的很好了,可以直接返回response,也可以继续递归。整套机制略显复杂,没有必要引入Chain这个东西,只需要提供找到下一个拦截器的方式即可!
它现在是这样
Response response = null;
if(能处理) {
response = DIY;
} else {
response = chain.proceed();
}
return response;
我觉得不如这样
Response response = null;
if(能处理) {
response = DIY;
} else {
response = InterceptHelper.getNextIntercept().intercept();
}
return response;
也就是把两个方法intercept.intercept,chain.proceed只留下前者就可以了。
还有一种很有趣也很厉害的思路:
我一开始觉得有点像策略+责任链,但是拦截器不仅有对request的处理,还有对于response的处理,这是用遍历解决不了的。
所以可以把一个拦截器的任务分成两部分,一个是对于request的处理,一个是response。
在遍历的时候,只需要检测布尔值即可,比如boolean isSuccess = intercept.interceptRequest,如果成功,再逆序遍历,执行interceptResponse。
不过总的来说,像这种下去后,还要回来的场景,递归是最合适的。如果直接按单个执行,那么还是遍历最好。
(老子感觉责任链和策略的区别就是在这里!!前者是算法中可以考虑返回结果,可以继续递归;后者的算法是一道完整算法)
常规责任链怎么设计的
我看了Android源码设计模式与实战的对应章节,它是给一个链接设置后驱,可以自己return结果,也可以继续执行后驱。所以整个就是一个无限循环链表。
责任链的缺点显而易见
是无限循环链表,性能差