Android源码看设计模式(十六)--------关于责任链模式的Okhttp中拦截器分析

责任链模式

定义:

使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系,将这些对象连成一条链,并沿着这条链去传递该请求,直到有对象处理它为止

使用场景

  1. 多个对象可以处理同一个请求,但具体由那个对象处理则在运行时动态决定
  2. 在请求处理者不明确的情况下向多个对象中的一个提交一个请求
  3. 需要动态的指定一组对象处理请求

责任链模式的写法

UML图如下:
这里写图片描述

  • AbstractHandler:抽象处理者角色,声明一个请求处理的方法,并在其中保持一个对下一个处理节点Handler对象的引用
  • ConcreateHandler:具体处理者角色,对请求进行处理,如果不能处理则将该请求转发给下一个节点上的处理对象
  • AbstractRequest:抽象请求者,其内声明一个获取请求级别的方法,与抽象处理者中返回的处理级别保持对应,什么级别的处理逻辑就对应什么样的请求级别
  • ConcreteRequest:具体请求者

设想一个场景:外出公干费用5万,回来之后上报组长报销费用,可是组长只能报销500一下的,然后组长上报部门主管,可是部门主管只能报销5000以下,之后上报老板…..这个过程中“我”只和“组长”有对接,但是具体是谁处理,并不关心,在乎的只是报账的结果,这就是责任链模式的本质,可以很好的将请求的发起者和处理者解耦

定义抽象处理者:抽象领导者

public abstract class Leader {
    protected Leader nextHandler;   //上一级的领导处理者
    public final void handleRequest(int money) {
        if (money <= limit()) {
            handle(money);
        } else {
            if (null != nextHandler) {
                nextHandler.handleRequest(money);
            }
        }
    }

    /**
     * 自身能批复的额度权限
     * @return 额度
     */
    public abstract int limit();

    /**
     * 处理报账行为
     * @param money 具体金额
     */
    public abstract void handle(int money);
}

创建具体处理者:具体领导者,组长、主管、经理、老板

//组长
public class GroupLeader extends Leader {
    @Override
    public int limit() {
        return 100;
    }

    @Override
    public void handle(int money) {
        System.out.println("组长审批报销"+money+"元");
    }
}

//主管
public class DirectorLeader extends Leader {
    @Override
    public int limit() {
        return 5000;
    }

    @Override
    public void handle(int money) {
        System.out.println("主管审批报销"+money+"元");
    }
}

//经理
public class ManagerLeader extends Leader {
    @Override
    public int limit() {
        return 10000;
    }

    @Override
    public void handle(int money) {
        System.out.println("经理审批报销"+money+"元");
    }
}

//老板
public class BossLeader extends Leader {
    @Override
    public int limit() {
        return Integer.MAX_VALUE;
    }

    @Override
    public void handle(int money) {
        System.out.println("老板审批报销"+money+"元");
    }
}

客户端调用:

public class Client {
    public static void main(String[] args) {
        //构建各个领导对象
        GroupLeader groupLeader = new GroupLeader();
        DirectorLeader directorLeader = new DirectorLeader();
        ManagerLeader managerLeader = new ManagerLeader();
        BossLeader bossLeader = new BossLeader();

        //设置上一级的领导处理对象
        groupLeader.nextHandler = directorLeader;
        directorLeader.nextHandler = managerLeader;
        managerLeader.nextHandler = bossLeader;

        //发起报账申请
        groupLeader.handleRequest(50000);

        //这里的5000应该是申请人提出的,申请人是具体请求者
    }
}

这里请求的发起可以从责任链的任何一个节点处开始,同时也可以改变责任链内部传递的规则,如果主管不在,完全可以跨过主管从组长直接将请求转送给经理

OkHttp拦截器

okhttp中添加各种拦截器以分别处理:详见okhttp整体流程
RealCall#getResponseWithInterceptorChain

Response getResponseWithInterceptorChain() throws IOException {
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors());
    interceptors.add(retryAndFollowUpInterceptor);
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    interceptors.add(new CacheInterceptor(client.internalCache()));
    interceptors.add(new ConnectInterceptor(client));
    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
    interceptors.add(new CallServerInterceptor(forWebSocket));
    //将所有的拦截器串成一条chain链
    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());
    //执行proceed方法获取响应
    return chain.proceed(originalRequest);
  }

RealInterceptorChain#proceed方法:

public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec,
      RealConnection connection) throws IOException {

    if (index >= interceptors.size()) throw new AssertionError();
    calls++;

    .........

    // 判断每一个截获器都有对应的处理,没有则创建RealInterceptorChain,即是创建当前的类,不断的迭代
    RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec,
        connection, index + 1, request, call, eventListener, connectTimeout, readTimeout,
        writeTimeout);
    Interceptor interceptor = interceptors.get(index);
    //并执行当前的截获器的intercept方法,这个方法其实就是递归调用,若没有形成递归,就是中断了请求
    Response response = interceptor.intercept(next);

    // Confirm that the next interceptor made its required call to chain.proceed().
    if (httpCodec != null && index + 1 < interceptors.size() && next.calls != 1) {
      throw new IllegalStateException("network interceptor " + interceptor
          + " must call proceed() exactly once");
    }

    .........

    return response;
  }

这里我们可以看到具体处理者就是截获器,详见截获器中的详细介绍

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值