整体概述
这个是我看完Retrofit的源码后,站在一个高的维度俯瞰整个Retrofit的架构得到的结论。
Retrofit的出现就是对OKHttp做了一个二次封装,为什么要封装?我认为核心目的就是让使用更加的方便。都对哪里进行了封装?
- 封装了请求参数。改为使用注解的形式,使使用更加的方便,RESTful风格可读性更强。
- 封装了请求过程。OKHttp中我们需要自己执行请求和回调,这个过程Retrofit帮我们封装了。
- 封装了结果的处理。这里分两个部分
- 数据解析
- 回调内容
可以说Retrofit通过对以上部分的封装,使得开发者只需关心参数,接口,结果即可,中间环节都不需要关心。
阅读思维导图
基本使用
下面例子来自Retrofit官网https://square.github.io/retrofit/
定义接口
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
使用Retrofit生成service
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
执行请求
Call<List<Repo>> repos = service.listRepos("octocat");
上面就是一个最简单的使用例子,我们自己项目中一般都做了更加复杂的封装。不过万变不离其宗,上面的例子才是最基础最原始的使用,其他也是基于此改造的。
架构设计
下图摘自 Stay大佬的Retrofit 分析 - 漂亮的解耦套路
这个图绘制的非常清晰,对照着这个图看Retrofit 源码,执行流程等会更加清晰。
源码分析
备注:本次源码分析基于2.9.0
首先看接口相关的。上面例子中定义了一个GitHubService的接口,里面一个方法listRepos()方法,上面有注解,我们看下Retrofit注解相关的内容
注解
关于注解的代码都在【package retrofit2.http; 】这个包下。
修饰方法的注解有:GET,POST,PUT,DELETE。。。
修饰参数的注解有:Field,Path,Header,Query,Body。。。
这些注解都是Retrofit库提供给我们实现网络请求的,既然是注解就有读取这些注解的地方,这个后面会看到。
修饰请求方法
@Documented
//表示此注解是修饰方法
@Target(METHOD)
//表示此注解运行时候也存在
@Retention(RUNTIME)
public @interface POST {
/**
* A relative or absolute path, or full URL of the endpoint. This value is optional if the first
* parameter of the method is annotated with {@link Url @Url}.
*
* <p>See {@linkplain retrofit2.Retrofit.Builder#baseUrl(HttpUrl) base URL} for details of how
* this is resolved against a base URL to create the full endpoint URL.
*/
String value() default "";
}
修饰请求参数举例
@Documented
//表示此注解是修饰方法
@Target(PARAMETER)
//表示此注解运行时候也存在
@Retention(RUNTIME)
public @interface Field {
String value();
/** Specifies whether the {@linkplain #value() name} and value are already URL encoded. */
boolean encoded() default false;
}
外观类Retrofit
Retrofit.java的类代码不长,仅仅600多行。首先看构造方法和主要的成员变量。
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
//这个是OKHttp里面的Call的工厂类
final okhttp3.Call.Factory callFactory;
//OKHttp中封装的一个表示url的类
final HttpUrl baseUrl;
//Converter.Factory的集合
final List<Converter.Factory> converterFactories;
//CallAdapter.Factory的集合
final List<CallAdapter.Factory> callAdapterFactories;
final @Nullable Executor callbackExecutor;
final boolean validateEagerly;
Retrofit(
okhttp3.Call.Factory callFactory,
HttpUrl baseUrl,
List<Converter.Factory> converterFactories,
List<CallAdapter.Factory> callAdapterFactories,
@Nullable Executor callbackExecutor,
boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
//build()方法,主要是暴露给外部调用构造Retrofit的
//这里使用了建造者模式
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
//build建造的时候设置
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
//build建造的时候没有设置的话,这里new一个新的
callFactory = new OkHttpClient();
}
//build建造的时候设置
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
//build建造的时候没有设置的话,这里使用默认的
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
//可以看出,下面几行代码主要是设置构建converterFactories,
//并把构建好的converterFactories传递给构造方法中
// Make a defensive copy of the converters.
//创建一个预设大小的List
List<Converter.Factory> converterFactories =
new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
//添加内置的BuiltInConverters
converterFactories.add(new BuiltInConverters());
//添加用户自定义的converterFactories
converterFactories.addAll(this.converterFactories);
//添加库提供的默认的converterFactories
converterFactories.addAll(platform.defaultConverterFactories());
//通过构造方法构建一个Retrofit
return new Retrofit(
callFactory,
baseUrl,
//Collections的静态方法unmodifiableList得到一个不可变的,不可修改的List。
unmodifiableList(converterFactories),
//Collections的静态方法unmodifiableList得到一个不可变的,不可修改的List。
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
通过上面的demo我们看出,这里通过建造者模式构建了一个Retrofit实例。Retrofit是对外的一个外观类,也就是使用了外观模式。构造方法看完了,也创建了Retrofit实例,紧接着我们看看上面例子中retrofit.create(GitHubService.class)这行代码。
public <T> T create(final Class<T> service) {
//首先校验这个ServiceInterface
validateServiceInterface(service);
//下面通过动态代理生成对象,处理请求
return (T)
Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] {service},
new InvocationHandler() {
private final Platform platform = Platform.get();
private final Object[] emptyArgs = new Object[0];
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
//排除默认方法,什么是默认方法,Java 8 引入了新的语言特性,就是接口中定义的非抽象非静态的方法
return platform.isDefaultMethod(method)
? platform.invokeDefaultMethod(method, service, proxy, args)
//最终核心执行的是这行代码,loadServiceMethod(method)
//得到一个ServiceMethod,然后执行ServiceMethod的invoke方法
: loadServiceMethod(method).invoke(args);
}
});
}
这里做一些校验工作
private void validateServiceInterface(Class<?> service) {
//首先是否是接口,不是抛异常
if (!service.isInterface()) {
throw new IllegalArgumentException("API declarations must be interfaces.");
}
Deque<Class<?>> check = new ArrayDeque<>(1);
check.add(service);
while (!check.isEmpty()) {
Class<?> candidate = check.removeFirst();
//不支持设置泛型参数
if (candidate.getTypeParameters().length != 0) {
StringBuilder message =
new StringBuilder("Type parameters are unsupported on ").append(candidate.getName());
if (candidate != service) {
message.append(" which is an interface of ").append(service.getName());
}
throw new IllegalArgumentException(message.toString());
}
Collections.addAll(check, candidate.getInterfaces());
}
//上面例子中并没有设置这个参数,先忽略
if (validateEagerly) {
Platform platform = Platform.get();
for (Method method : service.getDeclaredMethods()) {
if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
loadServiceMethod(method);
}
}
}
}
总结:service的创建是走的代理模式。而执行请求的地方是在代理方法里面。就是上面的invoke方法里面的内容,最终会执行到loadServiceMethod(method).invoke(args)方法。
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
...
}
loadServiceMethod
接着先分析loadServiceMethod方法,最终看执行invoke(args)的地方。这里先说关于invoke的结论:ServiceMethod是一个抽象类,invoke并没有实现,实现的地方在子类HttpServiceMethod中。然后再说loadServiceMethod,loadServiceMethod方法是获取一个ServiceMethod,会先调用ServiceMethod.parseAnnotations,然后调用HttpServiceMethod的parseAnnotations方法,最终生成一个ServiceMethod的实例。构建ServiceMethod实例的同时,也将CallAdapter,Converter等准备完成。
//Retrofit.java
ServiceMethod<?> loadServiceMethod(Method method) {
//先从缓存中取
ServiceMethod<?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
//解析注解,并拿到注解参数,最终得到一个ServiceMethod,这里后面在分析
result = ServiceMethod.parseAnnotations(this, method);
//拿到后写入缓存
serviceMethodCache.put(method, result);
}
}
return result;
}
//ServiceMethod.java
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
//这里构造出一个RequestFactory
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
//拿到返回类型
Type returnType = method.getGenericReturnType();
...
//不允许返回空类型
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
//调用HttpServiceMethod的解析注解方法,传入retrofit,方法,请求参数
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
这个RequestFactory 里面做了大量的准备工作,主要是将我们给方法和参数写的注解读取出来。包括请求类型,请求header,请求body,path参数等等。
//RequestFactory.java
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
return new Builder(retrofit, method).build();
}
RequestFactory build() {
for (Annotation annotation : methodAnnotations) {
//解析方法注解
parseMethodAnnotation(annotation);
}
...
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
//解析参数注解
parameterHandlers[p] =
parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
}
...
return new RequestFactory(this);
}
//解析方法中的注解,就是前面定义的各种注解,这里不在深入看了,
//只需要知道这里根据注解拿到对应参数即可
private void parseMethodAnnotation(Annotation annotation) {
if (annotation instanceof DELETE) {
parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
} else if (annotation instanceof GET) {
parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
} else if (annotation instanceof HEAD) {
parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
...
} else if (annotation instanceof retrofit2.http.Headers) {
String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
if (headersToParse.length == 0) {
throw methodError(method, "@Headers annotation is empty.");
}
headers = parseHeaders(headersToParse);
...
}
}
HttpServiceMethod.parseAnnotations
//HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
//是否是Kotlin协程挂起函数,这里先不分析Kotlin相关的
...
} else {
//得到返回类型
adapterType = method.getGenericReturnType();
}
//创建CallAdapter
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
...
//创建Converter
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
okhttp3.Call.Factory callFactory = retrofit.callFactory;
//是否是Kotlin协程挂起函数,这里不是,所以返回的是CallAdapted
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForResponse<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
} else {
//noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
return (HttpServiceMethod<ResponseT, ReturnT>)
new SuspendForBody<>(
requestFactory,
callFactory,
responseConverter,
(CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
continuationBodyNullable);
}
}
这个是核心方法,主要有三点:
- 创建CallAdapter
- 创建Converter
- 根据配置或者前面的参数判断构建哪个HttpServiceMethod
- CallAdapted 主要用于非处理Kotlin协程相关的请求,也就是我们常规的请求
- SuspendForResponse 处理Kotlin协程相关的请求
- SuspendForBody
下面我们分开来看这三点。
创建CallAdapter
//HttpServiceMethod.java
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
try {
//noinspection unchecked
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create call adapter for %s", returnType);
}
}
public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
return nextCallAdapter(null, returnType, annotations);
}
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
Objects.requireNonNull(returnType, "returnType == null");
Objects.requireNonNull(annotations, "annotations == null");
//根据skipPast得到开始查找的角标
int start = callAdapterFactories.indexOf(skipPast) + 1;
//循环在callAdapterFactories中查找符合returnType和annotations的CallAdapter.Factory
//然后CallAdapter.Factory会返回一个CallAdapter,这个是在后面的分析
for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
//找到对应的CallAdapter.Factory,然后执行get方法
CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
...
//没找到抛出异常
throw new IllegalArgumentException(builder.toString());
}
关于CallAdapter.Factory,还记得我们上面在分析Retrofit构建的时候有一个CallAdapter.Factory,在例子中我们并没设置CallAdapter.Factory,其实CallAdapter.Factory是用来生成CallAdapter,而CallAdapter又是根据(Type returnType)这个参数来决定的。
public Retrofit build() {
...
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
//上面官方例子中没有添加callAdapterFactories,所以是空的,
//所以仅仅添加了platform.defaultCallAdapterFactories(callbackExecutor)
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
...
return new Retrofit(
callFactory,
baseUrl,
unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories),
callbackExecutor,
validateEagerly);
}
这里还有一个细节,我们自定义的callAdapterFactories在前面,Retrofit提供的默认的defaultCallAdapterFactories在后面,也就是优先去找我们后来自己添加的。
下面看defaultCallAdapterFactories方法
//Platform.java
List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
@Nullable Executor callbackExecutor) {
DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
//如果是Java8添加一个CompletableFutureCallAdapterFactory.INSTANCE,
//否则的话, 只有一个DefaultCallAdapterFactory
//这里hasJava8Types为true,原因可以自行去看findPlatform方法
return hasJava8Types
? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
: singletonList(executorFactory);
}
接着去看DefaultCallAdapterFactory,上面nextCallAdapter方法会执行到这个get方法,最终是返回一个CallAdapter,例子中returntype为Call<List>,所以会走DefaultCallAdapterFactory的创建CallAdapter的过程。
public @Nullable CallAdapter<?, ?> get(
Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
...
final Executor executor =
Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
? null
: callbackExecutor;
//这里是创建了一个CallAdapter
return new CallAdapter<Object, Call<?>>() {
@Override
public Type responseType() {
return responseType;
}
@Override
public Call<Object> adapt(Call<Object> call) {
//这里是核心方法,因为最终会调用到这里
return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
}
};
}
创建Converter
还是回到HttpServiceMethod的parseAnnotations方法
//HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
boolean continuationWantsResponse = false;
boolean continuationBodyNullable = false;
Annotation[] annotations = method.getAnnotations();
...
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
..
}
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
Annotation[] annotations = method.getAnnotations();
try {
//跟callAdapter类似,调用retrofit的方法
return retrofit.responseBodyConverter(responseType, annotations);
} catch (RuntimeException e) { // Wide exception range because factories are user code.
throw methodError(method, e, "Unable to create converter for %s", responseType);
}
}
//Retrofit.java
public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
return nextResponseBodyConverter(null, type, annotations);
}
//可以看到跟callAdapter类似,又是去converterFactories这个List里面找对应type, annotations的Converter
public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
@Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
Objects.requireNonNull(type, "type == null");
Objects.requireNonNull(annotations, "annotations == null");
int start = converterFactories.indexOf(skipPast) + 1;
for (int i = start, count = converterFactories.size(); i < count; i++) {
//找到能够处理当前type, annotations的Converter并返回
Converter<ResponseBody, ?> converter =
converterFactories.get(i).responseBodyConverter(type, annotations, this);
if (converter != null) {
//noinspection unchecked
return (Converter<ResponseBody, T>) converter;
}
}
//省略部分异常处理
...
throw new IllegalArgumentException(builder.toString());
}
这次还是回到Retrofit建造者方法中,也就是构建Retrofit的必经之路,看下converterFactories的添加,这里添加了一个BuiltInConverters,然后添加用户自己设置的converterFactories,然后添加platform.defaultConverterFactories(),例子中虽然没添加,但是我们一般情况下都会添加一个GsonConverterFactory
返回CallAdapted
通过上面的分析这里并没有用Kotlin挂起函数,所以isKotlinSuspendFunction为false,返回一个CallAdapted,CallAdapted是HttpServiceMethod的子类,并且是final的静态内部类。现在我们可以在回到loadServiceMethod小结讲的loadServiceMethod(method).invoke(args)方法,最终调用到了HttpServiceMethod,而invoke又调用了adapt方法,最终调用到了子类CallAdapted中的adapt方法,最终调用了CallAdapter的adapt方法
//HttpServiceMethod.java
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(
RequestFactory requestFactory,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
上面分析完callAdapter执行的流程了,那么Converter在哪里执行呢?答案是在OkHttpCall中,看HttpServiceMethod.invoke方法中构造了一个OkHttpCall,我们很容易联想到,这个OkHttpCall是不是用来做OKHttp请求的,接着去看下
OkHttpCall
OkHttpCall(
RequestFactory requestFactory,
Object[] args,
okhttp3.Call.Factory callFactory,
Converter<ResponseBody, T> responseConverter) {
//请求路径,参数相关
this.requestFactory = requestFactory;
this.args = args;
//okhttp3的请求工厂
this.callFactory = callFactory;
//Converter
this.responseConverter = responseConverter;
}
public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
call = getRawCall();
}
if (canceled) {
call.cancel();
}
//解析结果
return parseResponse(call.execute());
}
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
ResponseBody rawBody = rawResponse.body();
// Remove the body's source (the only stateful object) so we can pass the response along.
rawResponse =
rawResponse
.newBuilder()
.body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
.build();
int code = rawResponse.code();
//一些异常和特殊case处理
...
ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
try {
//执行
T body = responseConverter.convert(catchingBody);
return Response.success(body, rawResponse);
} catch (RuntimeException e) {
// If the underlying source threw an exception, propagate that rather than indicating it was
// a runtime exception.
catchingBody.throwIfCaught();
throw e;
}
}
看完OkHttpCall代码就是象我们想的那样,这里是真正执行OkHttp请求的地方,将前面准备好的参数和请求工厂,responseConverter传进来。异常直接返回,成功的话走responseConverter的convert转换数据。
用到的设计模式
简单的如外观模式,单例模式,建造者模式,观察者模式就不再细诉了。
动态代理:每个Service的构建都是通过动态代理实现的,可以说这个动态代理是Retrofit的核心入口,不光包含了请求参数的解析,好包含了CallAdapter,Converter的选择与构建。真正做到了按配置生成。
工厂方法模式:
创建CallAdapter使用了工厂方法模式
抽象工厂模式:
创建Converter对象使用了抽象工厂模式
适配器模式:
将某个类的接口转化为客户端期望的另一个接口表示,主要的目的是兼容性,让原本不匹配不能一起工作的两个类可以协同工作。使用到的CallAdapter就是用了适配器模式。
装饰器模式:
OkHttpCall对Call进行了装饰增强。
参考链接
https://github.com/square/retrofit
https://juejin.cn/post/6844903429811208199
https://www.jianshu.com/p/63b98f6f5301