retrofit

Retrofit的设计模式 -- 简单工厂模式

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

Retrofit中的简单工厂模式

在前面说的用Builder模式构造Retrofit的时候看到了下面的代码:

public Builder() {
      this(Platform.get());
    }

跟进去看看

class Platform {
  private static final Platform PLATFORM = findPlatform();

  static Platform get() {
    return PLATFORM;
  }

  private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("org.robovm.apple.foundation.NSObject");
      return new IOS();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }
  static class Java8 extends Platform {
      ......
  }
static class Android extends Platform {
      ......
  }
static class IOS extends Platform {
      ......
  }

可以看到这是经典的简单工厂模式,通过静态工厂方法findPlatform中的Class.forName区分工厂生产的产品,产品的抽象类是Platform,Android、IOS、Java8都继承Platform。
题外话:这里的Android平台

static class Android extends Platform {
    @Override public Executor defaultCallbackExecutor() {
      return new MainThreadExecutor();
    }

    @Override CallAdapter.Factory defaultCallAdapterFactory(Executor callbackExecutor) {
      return new ExecutorCallAdapterFactory(callbackExecutor);
    }

    static class MainThreadExecutor implements Executor {
      private final Handler handler = new Handler(Looper.getMainLooper());

      @Override public void execute(Runnable r) {
        handler.post(r);
      }
    }
  }

这里可以看到,切换到了UI线程,其实这里就是网络请求到数据以后线程切换的关键地方.
继续前面的简单工厂模式,然后现在要加一个Windows平台了,就必须

static class Windows extends Platform {
      ......
  }

并且修改静态工厂方法findPlatform,这样就会有疑问了,这样岂不是违反了open-close原则,想到的办法就是用,为每一个平台建立一个Factory,每个Factory继承一个抽象的Factory

public abstract class PlatformFactory {
    abstract Platform findPlatform();
}

public class AndroidFactory extends PlatformFactory {

    @Override
    Platform findPlatform() {
        try {
            Class.forName("android.os.Build");
            if (Build.VERSION.SDK_INT != 0) {
                return new Android();
            }
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
    }
}

这样就是抽象工厂方法,当要增加Windows平台时就建立一个工厂生产Windows就行了

public class WindowsFactory extends PlatformFactory {

    @Override
    Platform findPlatform() {
        try {
            
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
    }
}

那么问题来了,Retrofit大牛们为啥不用抽象工厂模式呢?
个人认为:
1、首先这个Platform是不对外公布的类
2、一般情况下Retrofit支持的平台不会轻易增加,就是很少改动这里
3、需要引入抽象层,增加多个具体工厂类,维护成本也更大
所以在写代码时候,当用到设计模式设计代码时,一定要权衡利弊,冷静分析,不同场景用不同的方法,为了有个参考对比两种形式请看Retrofit中的抽象工厂模式.

上一篇下一篇

猜你喜欢

热点阅读