retrofit

Retrofit的设计模式-- 抽象工厂模式

2017-03-06  本文已影响76人  gzfgeh

Retrofit中的抽象工厂模式

前面说了项目中的设计模式 -- 简单工厂模式,为了有对比现在来理解一下抽象工厂模式,巧的是Retrofit中正好有抽象工厂模式的例子 -- CallApdater

public interface CallAdapter<T> {
  Type responseType();
  <R> T adapt(Call<R> call);
  abstract class Factory {
    public abstract CallAdapter<?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }
}

当时看到这种形式也是一脸懵逼,从来没有见过这种写法,当时还想了想如果实现这个CallAdapter接口,要实现这个Factory类吗???,后来仔细一想这就是抽象工厂模式形式,并且这样写还省了一个文件(本来是抽象产品接口和抽象工厂类是分开放在不同的两个文件的),CallAdapter这个类的作用就是调度网络请求的线程,CallAdapter作用非常大,CallAdapter作用非常大,CallAdapter作用非常大,本身是抽象工厂模式,并且里面的adapt方法用了适配器模式,把默认的Call适配到客户端想要用的Adapter上
Retorfit中默认有CallAdapter接口的实现,看Retrofit中的默认实现:

final class DefaultCallAdapterFactory extends CallAdapter.Factory {
  static final CallAdapter.Factory INSTANCE = new DefaultCallAdapterFactory();

  @Override
  public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }

    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public <R> Call<R> adapt(Call<R> call) {
        return call;
      }
    };
  }
}

但是一般情况下都是用现在RxJava,所以就有了RxJavaCallAdapterFactory供我们使用,这里可以看到抽象工厂模式的可扩展性非常好.

public final class RxJavaCallAdapterFactory extends CallAdapter.Factory {

  @Override
  public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
     ......
    }

    CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType, scheduler);
    ......
    return callAdapter;
  }

  private CallAdapter<Observable<?>> getCallAdapter(Type returnType, Scheduler scheduler) {
    ......
    return new SimpleCallAdapter(observableType, scheduler);
  }

这个抽象工厂CallAdapter#Factory中只有一个抽象方法get方法,返回CallAdapter接口,这个接口就是抽象工厂中的抽象产品接口,Factory就是抽象工厂类,RxJavaCallAdapterFactory和DefaultCallAdapterFactory就是具体工厂类,这两个具体工厂类生产出来的产品就是SimpleCallAdapter(RxJavaCallAdapterFactory#getCallAdapter中其实是用了策略模式,这里只是举例不必深究啊)和CallAdapter

static final class SimpleCallAdapter implements CallAdapter<Observable<?>> {
    private final Type responseType;
    private final Scheduler scheduler;

    SimpleCallAdapter(Type responseType, Scheduler scheduler) {
      this.responseType = responseType;
      this.scheduler = scheduler;
    }

    @Override public Type responseType() {
      return responseType;
    }

    @Override public <R> Observable<R> adapt(Call<R> call) {
      Observable<R> observable = Observable.create(new CallOnSubscribe<>(call)) //
          .lift(OperatorMapResponseToBodyOrError.<R>instance());
      if (scheduler != null) {
        return observable.subscribeOn(scheduler);
      }
      return observable;
    }
  }


  new CallAdapter<Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public <R> Call<R> adapt(Call<R> call) {
        return call;
      }
    };

其实Retrofit中还有地方用到了抽象工厂模式,那就是GsonConverterFactory,抽象工厂的好处显而易见,可扩展性高,但是这里为啥不用简单工厂模式呢,怎么实现,实现的话客户端如何用?
个人认为:
1、这个CallAdapter是要对外公布的,他是要控制网络请求的线程调用
2、这个地方是易变的,会经常改动的

上一篇下一篇

猜你喜欢

热点阅读