第一篇:Retrofit主要类UML图
2016-05-06 16:07:09
1.先上一张Retrofit的代码结构图:

可以看到,Retrofit自身的结构很简单,代码量也不是很大。红色框部分是一些注解类,就是一些标记。
简单的看一下客户端是如何使用Retrofit的:
定义接口:
public interface WeatherDataService {
@GET("/wtr-v2/temp/realtime")
Call<MiWeatherData> getMiWeather(@Query("cityId") String cityId);
@GET("/wtr-v2/temp/realtime")
Observable<MiWeatherData> getMiWeatherObservable(@Query("cityId") String cityId);
@GET("/wtr-v2/temp/realtime")
MiWeatherData getMiWeatherCustomCallAdapter(@Query("cityId") String cityId);
}
客户端调用:
private void getWeather() {
retrofit = new Retrofit.Builder()
.baseUrl("http://weatherapi.market.xiaomi.com")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
service = retrofit.create(WeatherDataService.class);
Call<MiWeatherData> result = service.getMiWeather("101010100");
try {
Response<MiWeatherData> r = result.execute();
MiWeatherData data = r.body();
Log.e("David", "ResponseBody data = " + data);
if (data != null) {
Log.e("David", "RxLoaderCallback data = " + data.weatherinfo.SD);
Log.e("David", "RxLoaderCallback data = " + data.weatherinfo.cityid);
Log.e("David", "RxLoaderCallback data = " + data.weatherinfo.WS);
}
} catch (IOException e) {
e.printStackTrace();
}
}
2. 几个主要类的UML简图:
2.1 Retrofit和Retrofit.Factory

Retrofit和ServiceMethod使用了Builder模式(省略了Director和Abstract Product的Builder模式)来构建自己,Retrofit的作用很简单,传入需要的参数,构建一个Retrofit对象,然后通过动态代理的方式,得到我们自定义的方法接口的实例,参数中除了baseUrl之外,其他都是可选的,如果没设置会使用默认值。
ServiceMethod就是我们自己调用的方法做一层封装而已,包括解析方法使用的注解、参数等,同时提供方法,生成网络请求需要的Request和解析请求结果。
2.1 CallAdapter和CallAdapter.Factory

CallAdapt的作用是把Call转变成你想要返回的对象,起作用的是adapt方法,CallAdapter.Factory的作用是获取CallAdapter。ExecutorCallAdapterFactory的CallAdapter会将回调方法放到主线程中执行,DefaultCallAdapterFactory不是。两者的CallAdapter能够接受的返回值类型为Call<T>。很明显,RxJavaCallAdapterFactory的CallAdapter能够接受的返回值是Oservable<T>。如果想让的方法直接返回一个对象,可以自定义一个CallAdapter.Factory。代码如下:
private class MyCallAdapterFactory extends CallAdapter.Factory {
@Override
public CallAdapter<?> get(final Type returnType, Annotation[] annotations, Retrofit retrofit) {
return new CallAdapter<Object>() {
@Override
public Type responseType() {
return returnType;
}
@Override
public <R> Object adapt(Call<R> call) {
try {
return call.execute().body();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
};
}
}
Service方法和CallAdapter的对应关系如下:

2.3 Converter和Converter.Factory

Converter的作用是将网络请求结果ResponseBody转换为我们希望的返回值类型。Converter.Factory的作用是获取Converter,这里很明显采用了静态工厂模式。如果你不设置ConverterFactory,那么调用WeatherDataInterface的三个方法都会崩溃,提示:Could not locate ResponseBody converter for class MiWeatherData。这是因为使用了默认的BuiltInConverters,而我们的方法不满足获取到responseBodyConverter的要求,所以崩溃,代码截图如下:

所以,如果不想设置Converter,那么我们的方法返回值必须为ResponseBody或者Void,如果是ResponseBody,且有@Streaming注解,会使用StreamingResponseBodyConverter,否则使用BufferingResponseBodyConveter。这两者基本都是原封不动的返回ResponseBody。而VoidResponseBodyConverter返回null~感觉这点比较坑,干点什么不好,非要返回null
Retrofit提供了多个Converter供选择,比如将Json转换为Object的GsonConverterFactory,如下图:

这也是Retrofit的一大特点---足够的开放、灵活。
2.4 OkHttpCall

OkHttpCall继承自interface Call,主要的作用是调起执行网络请求以及返回当前请求状态状态,但是真正的网络请求其实在okhttp3.Call接口,接口定义如下:

这个接口的实现类是okhttp3.RealCall,可以发现,Retrofit的Call接口和okhttp3的Call接口定义几乎是完全一样的,目的当然是实现OCP,这样做的好处显而易见:
1.利于扩展,retrofit2.Call接口可以有其他的实现类,不一定非要用OkHttp,只不过OkHttpCall用的恰好是OkHttp而已。
2.解耦,为了实现第一个目的,retrofit2.Call接口的存在就是理所当然的。
2.5 ParameterHandler

这是一个辅助类,用于解析我们自己定义的Method,由于我们是通过注解的方式来表达各种信息,比如请求类型(POST、GET)、Query参数、Body等,因此需要解析出来。不在主线,因此不作分析,但是里面的实现蛮复杂的,是个细致活儿。
2.6 RxJavaCallAdapterFactory分析

CallAdapterFactory的作用及工作机理前面已经介绍过了,RxJavaCallAdapterFactory的作用也是一样的,只不过RxJavaCallAdapterFactory中内部又定义了三种CallAdapter:ResponseCallAdapter、ResultCallAdapter和SimpleCallAdapter,根据返回值类型决定到底使用哪个,代码如下:

本质上处理流程是一致的,都是按照RxJava的套路执行请求并处理返回值的。
关于Retrofit中主要类的分解到此结束,之所以这么繁琐的画UML图,目的是为了更加深入的了解作者设计类的思路,比如作者是如何考虑一个类的功能、边界在哪里等。
第一篇:Retrofit主要类UML图的更多相关文章
- 【面试 JDK】【第一篇】Object类面试详解
1.Object类有哪些方法 1>clone()方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则抛出CloneNotSupportedException异 ...
- 如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现
一,话说天下大事 前不久看到lufy的博客上,有一位朋友想要一个RPG游戏引擎,出于兴趣准备动手做一做.由于我研究lufylegend有一段时间了,对它有一定的依赖性,因此就准备将这个引擎基于lufy ...
- 关于ER图和UML图之间的对比
ER图与UML图 ER图:实体-联系图(Entity-Relation Diagram)用来建立数据模型,在数据库系统概论中属于概念设计阶段,ER图提供了表示实体(即数据对象).属性和联系的方法,用来 ...
- java 线程池第一篇 之 ThreadPoolExcutor
一:什么是线程池? java 线程池是将大量的线程集中管理的类,包括对线程的创建,资源的管理,线程生命周期的管理.当系统中存在大量的异步任务的时候就考虑使用java线程池管理所有的线程.减少系统资源的 ...
- UML图学习之二 类图
类图(ClassDiagrams)是根据系统中的类以及各类之间的关系描述系统的静态视图.类图不仅显示系统内信息的结构,还描述系统内这些信息的行为.类图的一个重要目的是为其他图(如顺序图.交互图)定义一 ...
- eclipse下生成Java类图和时序图,生成UML图
1.安装和使用AmaterasUML 安装AmaterasUML前,需要先安装GEF采用eclipse在线安装方式安装就好.eclipse在线安装GEF的地址:http://download.ecli ...
- java 类与类之间的关系 及uml图
类与接口之间的关系 : 继承 类与类之间的关系 :继承关系 包含关系 类与对象之间的关系 : 实例 UML 类图中类与类之间的关系: 泛化关系(generalization) 关联关系(associ ...
- C++第一篇--类的引入
C++第一篇--类的引入 1. 用C语言输出两个人的信息 Person1.c:通过字符实现 #include <stdio.h> int main(int argc,int **argv) ...
- UML图类,接口之间的关系
UML图类之间的关系(来自大话设计模式中的一张图,代表了类,接口之间的各种关系)
随机推荐
- pyqt4学习笔记
信号与槽机制 信号与槽机制作为Qt最重要的特性,提供了任意两个Qt对象之间的通信机制.其中,信号会在某个特定情况或动作下被触发,槽是用于接收并处理信号的函数.例如,要将一个窗口中的变化情况通知给另一个 ...
- 理解RESTful
REST全称为Representational State Transfer,可以翻译为“表现状态转换”,是由是Roy Thomas Fielding在他2000年的博士论文中提出的,目的是为了得到一 ...
- javascript 随笔
document.execCommand("SaveAs",true,"aaa"); //将当前web页面另存为文件.第三个参数为文件名,可以自己设置,为空的时 ...
- PHP基础知识之————PHP Web脚本中使用FFmpeg
简介 本文将尝试指出在PHP Web脚本中使用FFmpeg时需要了解的所有重要事项.它还将显示一些使用示例,以使事情更清楚.这个想法也可以应用到其他web脚本语言. 从PHP脚本调用命令行工具 选择一 ...
- c++ STL 学习记录 草稿。
非常丑陋的尝试实现stl.慢慢修改吧. 1)简单实现 vector和list. 2)思索如何开始编写算法. 1,所有容器继承一个抽象容器.那么算法就可以使用抽象基类的next方法来遍历元素. 容器间耦 ...
- ThinkPHP的URL重写+路由+伪静态,实现SEO效果。
1.URL重写,隐藏网址中的Index.php. ThinkPHP 作为 PHP 框架,是单一入口的,那么其原始的 URL 便不是那么友好.但 ThinkPHP提供了各种机制来定制需要的 URL 格式 ...
- IE下,js改变绝对定位的属性不生效
如果想要动态改变定位位置的值,例如改变TOP的值,IE下必须要给TOP一个初始值,不然不生效..
- Java学习之Iterator(迭代器)的一般用法 (转)
迭代器(Iterator) 迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构.迭代器通常被称为"轻量级"对象,因为创建它的代价 ...
- ajax中使用post传值数组array
如果我们在data中想放入array的参数,根据在网上搜索的结果有如下方法,但是没有一个成功的……我还是贴出来,别人成功了,也许是我哪里不对,日后也许还有机会研究..在文章的最后贴出了转化为json的 ...
- jquery trigger 触发事件小计 -- 关于a标签
jquery -- trigger触发执行事件方法虽然好用,偶尔也会出些小问题. 在最近得一个项目中需要触发a标签的点击事件时,我就遇到了点小问题.我很想当然的写层这样:$("a" ...