OKHttp拦截器之责任链模式

OKHttp中一个比较有意思的地方就是提供了拦截器机制

说起这个拦截器,它使用了一个比较冷门的设计模式,叫责任链模式

我翻阅了若干设计模式的书籍,对责任链模式基本上都是一笔带过没有过多的描述

关于责任链模式的写法,网上有很多,大多比较简单,而OkHttp的责任链写法比较独特。下面就采用OkHttp的写法 来实现一个简单的责任链模式,理解了这个责任链模式,也就理解了OkHttp的拦截器原理

在这个示例中 我们模拟一个邮件服务器 设计若干种邮件处理器

用户选择多个邮件处理器组成一个责任链,将邮件交给该责任链之后 邮件依次使用各个处理器进行处理,得到最终的处理结果

语言过于苍白,程序员都是直接看源码,解释都写在了代码的注释里面

 

首先定义邮件和邮件处理器接口

public interface Processor {

    Email handleEmail(Email email, int nextpos, ArrayList<Processor> processors);

}

 

 

public static class Email {

    //处理结果

    String result = "";

}

定义链式模型中一个链条

public static class EmailChain {

 

    private int pos;

    private ArrayList<Processor> processors;

    public Email email;

 

 

    public EmailChain(int pos, Email email, ArrayList<Processor> processors) {

        this.pos = pos;

        this.processors = processors;

        this.email = email;

    }

 

    //核心方法 每个链条结有一个proceed方法,这个方法决定要不要去链接下一个链条结

    public Email proceed(Email email) {

        if (pos < processors.size()) {

            //如果当前的位置不是最后一个链条结 则获取当前链条结所拥有的处理器

            Processor processor = processors.get(pos);

            //如果能够捕获到处理器,就使用处理器对email进行处理

            Email resultEmail = processor.handleEmail(email, pos + 1, processors);

            return resultEmail;

        else {

            //否则直接返回 不做处理

            return email;

        }

    }

}

定义三种邮件处理器

public static class Processor1 implements Processor {

     

    @Override

    public Email handleEmail(Email email, int nextpos, ArrayList<Processor> processors) {

        //当前处理器可以继续将email交给下一个环扣 等待下一个环扣的反馈,也可以选择拦截处理结果

        // 在这个处理器中,处理器选择优先处理,处理完成后再交接给下一个链条结

        email.result = email.result + " 添加重要性标签";

        EmailChain next = new EmailChain(nextpos, email, processors);

        email = next.proceed(email);

        return email;

    }

}

 

public static class Processor2 implements Processor {

 

    @Override

    public Email handleEmail(Email email, int nextpos, ArrayList<Processor> processors) {

        //当前处理器可以继续将email交给下一个环扣 等待下一个环扣的反馈,也可以选择拦截处理结果

        // 在这个处理器中,处理器选择将处理权限优先交给下一个链条结处理,等待返回后自己再处理

        EmailChain next = new EmailChain(nextpos, email, processors);

        email = next.proceed(email);

        email.result = email.result + " 移入指定文件夹" ;

        return email;

    }

}

 

public static class Processor3 implements Processor {

 

    @Override

    public Email handleEmail(Email email, int nextpos, ArrayList<Processor> processors) {

        //当前处理器可以继续将email交给下一个环扣 等待下一个环扣的反馈,也可以选择拦截处理结果

        // 在这个处理器中,处理器选择优先处理,处理完成后再交接给下一个链条结

        email.result = email.result + " 添加提醒";

        EmailChain next = new EmailChain(nextpos, email, processors);

        email = next.proceed(email);

        return email;

    }

}

测试代码

public static void main(String[] args) {

 

 

    //定义链式结构及其对应的处理器

    ArrayList<Processor> processors = new ArrayList<>();

    processors.add(new Processor1());

    processors.add(new Processor2());

    processors.add(new Processor3());

 

    //初始的邮件数据

    Email email = new Email();

 

    //整个任务 抽象成链条中一个链条结,每个结点中有一个处理器, 环环相扣行成一条链条 链条有多长,其实是由处理器的数量决定的

    //在开始建立这个链条的时候,我们从链条的顶端开始新建链条结 第一个结点的位置就是0

    EmailChain chain = new EmailChain(0, email, processors);

 

    //邮件服务器 只需要关注从离他最近的第一个环扣中得到处理后的信息

    Email resultEmail = chain.proceed(email);

    System.out.println("finalResult = " resultEmail.result);

}

输出结果
finalResult =  添加重要性标签 添加提醒 移入指定文件夹
上一篇:okhttp下载文件并直接显示到手机上


下一篇:OkHttp应用和封装