本人以前写的Android网络框架时介绍过Retrofit,原文在这里,也做过对Retrofit库进行简单的封装工作, Github源码再这里, 在这里就不多说了。当时使用的时候简单看了一些源码,发现源码中大量使用设计模式,包括Facade、Factory、Proxy、Strategy、Adapter、Observer等等,是我辈学习设计模式的好案例。当然Android源码也大量用设计模式, 只是太分散了。
不要为了设计而设计
在这里多说一些, 不要为了设计模式而设计,相反是因为写也块的时候,正好可以能用这种设计模式而已, 总之好的代码是重构出来的,不是设计出来的。
就像金庸武侠小说里风清扬的独孤九剑一样, 虽然只有短短的九个招式, 但每个招式又有不同的变化。这也是为什么比较喜欢C语言的地方, 语法就那么简单,但不同的组合就能干任何事情。
如何阅读源码
本人一直的观点是”授人予鱼、不如授人予渔”,这是我写这些的东西的目的之一。其实没有太多的技巧, 就是死磕,但是要有策略的死磕。好吧, 你们有福了, 正好最近看到一篇相关的,里面也讲一些有用的技巧,分享给大家, 下面文章来自卖桃说本人MacTalk:
与编程一样,阅读别人的源代码永远不是一件轻松的事,或者说,是一件困难的事情,需要持续的投入,阅读、研究、把玩、实践。很多人觉得拿到了源代码就像买了本书一样,放到书柜上,马上就有种学会了的感觉,但真正实践起来才会体验到强烈的挫败感。大部分情况下,读不下去,不是方法不好,而是投入度不够。
阅读源代码,一定要找到好的开源项目。什么是好的项目?口碑好且应用广泛的项目就是好项目,比如 Docker、Spring、OpenResty,都是非常好的阅读素材。另外,完善的文档和足够的 test case 覆盖率,都是衡量一个开源项目是否优秀的标准。很多人说,代码即文档,好的代码本身就是自解释的。但是,对于规模宏大的开源软件来说,没有文档是不可想象的。所以在阅读源代码之前,一定要读文档。尽管读了文档之后,你可能不知道代码的技术细节,但至少可以了解项目的轮廓。结合开源项目的代码目录,差不多可以绘制出一个粗粒度的整体架构图。
然后为每个目录(或模块)做记录和标识,逐一阅读,或者直接去读你最感兴趣的部分。
我读源代码喜欢自顶向下的方式,先把整体脉络理清楚,然后按照模块去阅读代码,把类和类、函数和函数之间的调用关系记录下来,如果可以进行逆向工程,用类似 Intelli IDEA 这样的工具把代码之间的调用关系用 Diagrams 展现出来,阅读会更加直观一些。
另外,阅读 test case 同样能帮助你理解作者的代码设计意图,正常情况下,测试用例都是从文档和设计衍生出来的,而不是完成了代码再写 test case。阅读测试用例,可以让你更清晰的知道对应的类和函数想要做什么事情(笔者注:测试用例很重要)。
阅读源代码需要顺手的工具,我自己喜欢用 Vim,配合 NERDTree、Cpmmand-T、ctags、taglist 等插件,Vim 可以成为一款优秀的代码浏览工具,而且非常轻量级。你可以通过命令行迅速打开、关闭、查找和索引程序,并进行有效的关联跳转(静态代码)。如果你不习惯,也可以用 Sublime Text,Atom 等工具。当然,如果你要进行调试和跟踪,那最好使用相关程序栈的 IDE 工具了,比如 Eclipse、Jet Brain 系列工具,Xcode 等,这样你可以在 debug 状态跟踪所有的函数调用和变量参数在执行时间线上的变化。(笔者注:Emacs也很好,也是本人比较喜欢的)
重复一句,工具和方法永远不是最重要的,去读,并在遇到困难的时候,看不明白的时候,咬牙坚持下去,抽丝剥茧,逐个击破。最终,你会在冰冷黑暗的二进制世界里面看到一张地图,找到一座灯塔,然后去解释和还原这个底层世界里每一个细微方面的语义,重建出高层次的抽象概念和关系(这个观点和笔者一致)。
正文
上面扯了那么多还没进正文, 看来要分两篇来下了,本文主要分析的源码版本是2.0。
Retrofit 可以分为注解解析(Request 生成),请求执行,请求回调(异步处理),响应体转化几个部分。其中请求执行与请求回调可以算作一个部分,并且请求回调也可以没有,同步请求操作Call 直接执行的接口 execute。
还是上一张详细的设计图把, 这里偷一下懒吧, 不自己画了, 这个以前帖过,现在版本总体设计没有什么变化。
主要是围绕着 converter,CallAdapter 设计的整个框架,剩下的下篇再说吧!