细细品读 Retrofit 的设计之美一

前言

Retrofit 是这两年比较流行的网络通讯库,之所以流行自然有它的优点,首先是大厂 Square 公司开源之作,俗话说大厂出品,必须精品。
作为网络通讯框架,基本的组成部分就是三大块:1. 请求体部分。2. 响应体部分。3. 与UI层回调部分。

Retrofit的使用这里就不细说了,我们从构建Retrofit对象谈起。

首先:构建者Builder模式

整体看很明显有个构建者Builder模式,Builder模式在Android中是很常见的一种设计模式,它的优点很明显一般情况一个框架都是需要灵活自由的配置参数属性的,如果不用Builder模式,都改成setter、getter,那初始化一个Retrofit对象就显得复杂和臃肿了。而这里Builder模式加上链式调用方式,为Retrofit框架的参数配置增添了不少灵活和自由,而且代码可读性也增强了。

其实 Builder 模式的套路很简单,下面来个简单的伪代码Builder模式:

以上就是Builder模式的套路模板,外部Retrofit的对象的构建最终是在build()方法new出来返回。

Retrofit框架内部有好多地方都用到了Builder模式,也是为了方便自由配置参数的。

Builder模式在Android开发中最常见的就是AlertDialog.Builder,可以自由的配置对话框的标题、内容、内容设置来源、确认取消等按钮事件等等。有兴趣的可以去了解下AlertDialog的源码,基本也是上面模板的套路。

代理模式

构建好 Retrofit 对象后,大家都知道这个框架网络请求的通讯接口 api 都是 Interface 接口中声明的,框架本身为了与网络请求业务做解耦用了动态代理的方式,为业务通讯接口生成代理对象,当代理对象调用业务接口方法 api 的时候,动态代理类就能监测到并回调,这时候就可以做网络框架该有的功能:解析通讯业务接口,生成网络请求体便于供应给底层OkHttp 做具体的网络请求工作。其实就是框架本身没有办法直接使用业务接口,所以请了一个代理中介对象去间接的访问业务接口,来完成相关的业务功能。

来看看create方法是如何创建出ApiService接口的对象的。

通过Proxy.newProxyInstance方法动态创建了代理对象,也就是上文create方法返回的mApiService对象。是不是很懵逼,为什么Proxy.newProxyInstance方法就能创建出代理对象,而且又正好是ApiService.class这个接口对象呢,是怎么创建出来的?带着这些问题,我们来聊聊“代理模式”。

要搞清楚上面的这些问题,就得明白代理模式的套路,最重要就是区分清楚角色:
角色一:目标接口
角色二:目标对象
角色三:代理对象

这里先举个简单的例子,有个这样的场景:

Jerry是个程序员年纪大了眼看就要30岁了还是单身,家里人非常的着急,于是找到了隔壁老王(老王认识的妹纸比较多,为人热情)叫着帮忙介绍妹子给Jerry认识。

上面这个场景来区分下角色:
角色一:目标接口,大龄单身汪找妹子(要干的事情)
角色二:目标对象,单身程序员Jerry(需要找妹子的目标人物)
角色三:代理对象,皮条客隔壁老王(代表Jerry去找妹子)

这里创建三个文件:目标接口 IFindGirl、目标类Jerry、代理类ProxyLaoWan

使用的时候很简单:

这个例子中Jerry没有直接去找妹子“Tom”,而是通过了老王,这是一个典型的静态代理模式,Jerry把找妹子的事情委托代理给了老王,同样Jerry如果还有其它的事情,比如买最新的肾phone手机,可是国行的很贵,刚好老王要去香港,又委托老王买港版的iPhone X,于是就要IService目标接口中加入新的要干的事情buyPhone(),同样老王的类、Jerry类都需要实现相应的方法。如果Jerry不断的有新的事情要做,新的功能要扩展那需要修改的地方就比较多了不利于项目的扩展和团队开发。为此这样的需求就产生了动态代理模式。

先来看看套路模板:

Jerry如果还要委托老王给买手机,只要给目标接口加入buyPhone方法,然后Jerry实现这个方法,而代理者老王,不需要管都有什么具体的目标接口,通过Proxy.newProxyInstance创建的代理对象,就可以调用目标接口的方法。

介绍下Proxy.newProxyInstance方法:

第一个参数:目标对象的类加载器。因为这个代理对象是运行时才创建的,没有编译时候预先准备的字节码文件提供,所以需要一个类加载器来加载产生Proxy代理里的类类型,便于创建代理对象。
第二个参数:interfaces是目标接口数组
第三个参数:是代理对象当调用目标接口方法的时候,会先回调InvocationHandler接口的实现方法invoke。

到目前为止还是看不出来Proxy.newProxyInstance是怎么给我们创建代理对象的,下面分析下它的源码实现:

动态代理的源码实现

从上面代码中我们可以看出,最终的代理对象的创建是底层NDK来创建返回的,具体就不去看底层的实现了,大体了解到动态代理对象是通过这个构造方法来创建的。

经过上门对动态代理模式的一番学习和解释,现在回过头来看

create方法创建返回的正是ApiService接口的代理对象,每当代理对象调用目标接口里的方法时,动态代理对象就会回调InvocationHandler接口的invoke实现方法。

在Retrofit中,动态代理模式的角色划分:
角色一:目标接口(委托方法),ApiService接口方法
角色二:目标对象(委托方),ApiService.class
角色三:代理对象,create创建的mApiService对象。

至此就把 Retrofit 中,动态代理业务的网络通讯接口讲清楚了,好处就是非入侵的方式,把网络通讯api调用代理出来,然后在调用回调的 invoke方法里统一处理和准备网络框架需要构建的请求体,作为后续加入到请求队列任务池中进行具体的网络请求。动态代理模式也是 AOP 的一种实现方式,切片思想的一种。做过 Java EE 服务端开发的对于 Spring 的AOP 应该深有体会,动态代理与 Annotation 的结合真是完美,这一点在Retrofit的各种请求方式、参数、url 路径等等的注解就体现了。


文章有些长,这是第一篇,后面还会持续更新关于 Retrofit 的解读,不单单是让你懂的 Retrofit 的原理,还让你学会感受设计模式的美妙。感谢你的阅读。

与之相关

软件开发中的 10 条最佳指导原则

Android 面试 | 全站式导航

2017 | 我在 5 个月时间里分享了 98 篇文章

微信号:code-xiaosheng

公众号

「code小生」

(0)

相关推荐

  • 设计模式-创建型-建造者模式

    引言: 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.底盘.发动机.方向盘等各种部件.而对于大部分用户而言,无须知道这些部件的装配细节,也几乎不会 ...

  • 设计模式-结构型模式总结

    结构型模式主要处理类或对象的组合,关注于如何将现有类或对象组织在一起形成更大的结构. 适配器模式 将一个类的接口转换成客户希望的另外一个接口,使原本不能一起工作的类可以一起工作. 适配器模式属于补偿机 ...

  • 聊聊 Python 面试最常被问到的几种设计模式(下)

    聊聊 Python 面试最常被问到的几种设计模式(下)

  • 结构型设计模式总结

    Intro 前面几篇文章已经介绍完了所有的结构型设计模式,来做一个总结 结构型设计模式主要总结了一些类或对象组合在一起的经典结构,这些经典的结构可以解决一些特定应用场景的问题. 结构型模式包括:代理模 ...

  • 细细品读 Retrofit 的设计之美 二

    引言 在上一篇 细细品读 Retrofit 的设计之美一 后,我们了解了 Builder 构建者模式和(动态)代理模式在 Retrofit 中的做用,以及它们的使用套路.今天继续品读 Retrofit ...

  • 古典华贵 值得细细品读的四合院设计

    项目:兴华胡同贤德书院 案例简述:此次四合院设计设计师用简约的笔触构筑了空间的筋骨,细节处巧妙铺陈中式元素,诠释中式文化和现代简约的融合交汇,凸显出四合院的儒雅清新的非凡气质.看似朴实的院落里蕴藏着经 ...

  • 中国最美的100句诗词 值得细细品读

    留着学习! 图文分享转载自互联网

  • 20首春天绝美唐诗,值得细细品读

    春天是一个万物复苏的季节,大地回春的好日子.师徒特说:"春天的太阳甚至能给最普通的花带来新生."今天为大家准备了20首有关春光的诗词,让我们在诗词的海洋里,感受春天最美的风景. 0 ...

  • 唯美而富有哲理的句子,句句蕴含深意,值得在深夜细细品读!

    资讯早知道 2021-01-21 06:46 一.余生太长,我想牵着你的手,陪你到处逛逛:人生太长,我想挽着你的胳膊,陪你看夕阳. 二.我们的梦想就在高高的山巅上,如果每天攀登一阶,矢志不渝,梦想终会 ...

  • 朗读者30首美诗,每首都很美,值得收藏后细细品读!

    朗读者30首美诗,每首都很美,值得收藏后细细品读!记得关注我,每天都有你需要的干货分享哦!

  • 汀步设计的美,细细品!

    "汀步"空间体验,直白的感受就是 一步娘炮,两步扯蛋, 这步伐让男士们情何以堪 因此需要设计尺寸很重要 只要涉及尺寸合理,不存在扯蛋 低头也是风景,汀步其实可以更美哦 ↓ 这是一个 ...

  • 经典实在的感悟句子,唯美精致,值得细细品读

    昨天13:03 一 * 人生更大的可悲不是失去太多,只是计较太多,这也是导致一个人不开心的重要原因. 二 * 给自己一点时间.原谅做过许多傻事的自己.接纳自己,爱自己.过去的都会过去,该来的都在路上. ...

  • 180句国学经典名言名句、格言、警句!洞见人生大智慧,细细品读

    <诗经>1.言者无罪,闻者足戒.2.他山之石,可以攻玉.3.高山仰止,景行行止.4.如切如磋,如琢如磨.5.昔我往矣,杨柳依依:今我来思,雨雪霏霏.6.战战兢兢,如临深渊,如履薄冰.< ...