本文目标
Retrofit的源码设计模式分析
1.Builder 设计模式
static {
OkHttpClient httpClient = new OkHttpClient.Builder()
// 添加日志打印
.addInterceptor(new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.d("TAG", message);
}
}).setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
Retrofit retrofit = new Retrofit.Builder()
// 主路径
.baseUrl("http://ppw.zmzxd.cn/index.php/api/v1/")
// 添加转换工厂
.addConverterFactory(GsonConverterFactory.create())
// 配置 OkHttpClient
.client(httpClient).build();
// 创建 ServiceApi
mServiceApi = retrofit.create(ServiceApi.class);
}
2.动态代理设计模式
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service);
if (validateEagerly) {
eagerlyValidateMethods(service);
}
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public 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);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
create()这个方法,个人认为 Retrofit 能做到解耦就是因为动态代理的设计模式用得好,这种模式我们也是经常用到,有很多的体现形式.
3.工厂设计模式
abstract class Factory {
/**
* Returns a {@link Converter} for converting an HTTP response body to {@code type}, or null if
* {@code type} cannot be handled by this factory. This is used to create converters for
* response types such as {@code SimpleResponse} from a {@code Call<SimpleResponse>}
* declaration.
*/
public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
Annotation[] annotations, Retrofit retrofit) {
return null;
}
/**
* Returns a {@link Converter} for converting {@code type} to an HTTP request body, or null if
* {@code type} cannot be handled by this factory. This is used to create converters for types
* specified by {@link Body @Body}, {@link Part @Part}, and {@link PartMap @PartMap}
* values.
*/
public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return null;
}
/**
* Returns a {@link Converter} for converting {@code type} to a {@link String}, or null if
* {@code type} cannot be handled by this factory. This is used to create converters for types
* specified by {@link Field @Field}, {@link FieldMap @FieldMap} values,
* {@link Header @Header}, {@link HeaderMap @HeaderMap}, {@link Path @Path},
* {@link Query @Query}, and {@link QueryMap @QueryMap} values.
*/
public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
Retrofit retrofit) {
return null;
}
}
工厂设计模式又分为:简单工厂模式,工厂方法模式,抽象工厂模式。addConverterFactory(GsonConverterFactory.create())
好处就不用说了吧?当然这个地方还影藏着另一种设计模式,如有不了解你可以点击标题进入相应的链接。
4.Adapter 适配器模式
public interface CallAdapter<T> {
// 返回请求后,转换的参数Type类型
Type responseType();
// 接口适配
<R> T adapt(Call<R> call);
}
我们都知道 Retrofit 是支持 RxJava 的,我们看下是怎么办到的:
final class RxJavaCallAdapter<R> implements CallAdapter<R, Object> {
RxJavaCallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
boolean isResult, boolean isBody, boolean isSingle, boolean isCompletable) {
}
@Override public Type responseType() {
return responseType;
}
@Override public Object adapt(Call<R> call) {
OnSubscribe<Response<R>> callFunc = isAsync
? new CallEnqueueOnSubscribe<>(call)
: new CallExecuteOnSubscribe<>(call);
// 省略代码
OnSubscribe<?> func;
if (isResult) {
func = new ResultOnSubscribe<>(callFunc);
} else if (isBody) {
func = new BodyOnSubscribe<>(callFunc);
} else {
func = callFunc;
}
Observable<?> observable = Observable.create(func);
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
return observable;
}
}
这里用自己的话总结就是 RxJavaCallAdapter 实现了 CallAdapter 目标接口,调用 adapt 方法把 Call 转换适配成了 Observable。再通俗一点就是我想要的是 RxJava 的 Observable 对象,但是我只有 Call 这个怎么办?所以采用适配器模式。
5.模板设计模式
abstract class ParameterHandler<T> {
abstract void apply(RequestBuilder builder, @Nullable T value) throws IOException;
static final class Query<T> extends ParameterHandler<T> {
private final String name;
private final Converter<T, String> valueConverter;
private final boolean encoded;
Query(String name, Converter<T, String> valueConverter, boolean encoded) {
this.name = checkNotNull(name, "name == null");
this.valueConverter = valueConverter;
this.encoded = encoded;
}
@Override void apply(RequestBuilder builder, @Nullable T value) throws IOException {
if (value == null) return; // Skip null values.
String queryValue = valueConverter.convert(value);
if (queryValue == null) return; // Skip converted but null values
builder.addQueryParam(name, queryValue, encoded);
}
}
}
不到 20 个类,23 种设计模式 Retrofit 运用占了一大半,像 观察者设计模式 、策略设计模式 ,享元设计模式、门面设计模式、单例设计模式、原型设计模式 、装饰设计模式 等等都在其源码中有体现。
网友评论