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中的抽象工厂模式.