设计模式之工厂模式

简介:

工厂模式是创建型设计模式之一,基本思想其实就是将产品的相同部分抽象出来,然后由子类决定去产生不同的产品,用来解决复杂对象的生成。

UML类图


我们可以看出,工厂模式是个很简单的模式,那么我们去看看别人是如何实现工厂模式的

案例讲解

通过网络通信框架-Retrofit这篇我们可以看到,我们看到Retrofit会将请求封装成一个Call对象,然后通过该对象的enqueu()方法去发送网络请求,但是,如果我并不想返回这个对象呢,比如说支持Rxjava,我们了解Rxjava是对Observable对象发送的事件的订阅观察,那么我们想得到的应该是Observable对象,那么我们可以看出其它都一样,只是返回的对象不一样而已,或者我并不希望返回是在主线程,又如何改变回调的线程呢?我们看看Retrofit如何处理的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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接口中定义了该接口的抽象工厂,这里有一个抽象方法get(),这里我们看到它将返回类型,注解,以及retrofit等参数传入,只需要返回CallAdapter对象,那么我们看看Retrofit内部的两个适配器工厂DefaultCallAdapteFactory和ExecutoCallAdapterFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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;
}
};
}
}

这里我们看到默认是适配器工厂没有做什么改动,那我们看看ExecutorCallAdapterFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter<Call<?>> 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 new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor;
final Call<T> delegate;
ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
this.callbackExecutor = callbackExecutor;
this.delegate = delegate;
}
@Override public void enqueue(final Callback<T> callback) {
if (callback == null) throw new NullPointerException("callback == null");
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
if (delegate.isCanceled()) {
// Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
@Override public boolean isExecuted() {
return delegate.isExecuted();
}
@Override public Response<T> execute() throws IOException {
return delegate.execute();
}
@Override public void cancel() {
delegate.cancel();
}
@Override public boolean isCanceled() {
return delegate.isCanceled();
}
@SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
@Override public Call<T> clone() {
return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
}
@Override public Request request() {
return delegate.request();
}
}
}

这里我们看到ExecutorCallAdapterFactory类,在其它地方也并未做啥改动,不过他自定义了一个ExecutorCallbackCall用来执行自己的回调,即将回调回来的主线程都切换到子线程,那么我们再来看看Rxjava的回调工程又做了什么改变

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
@Override
public CallAdapter<?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
Class<?> rawType = getRawType(returnType);
String canonicalName = rawType.getCanonicalName();
boolean isSingle = "rx.Single".equals(canonicalName);
boolean isCompletable = "rx.Completable".equals(canonicalName);
if (rawType != Observable.class && !isSingle && !isCompletable) {
return null;
}
if (!isCompletable && !(returnType instanceof ParameterizedType)) {
String name = isSingle ? "Single" : "Observable";
throw new IllegalStateException(name + " return type must be parameterized"
+ " as " + name + "<Foo> or " + name + "<? extends Foo>");
}
if (isCompletable) {
// Add Completable-converter wrapper from a separate class. This defers classloading such that
// regular Observable operation can be leveraged without relying on this unstable RxJava API.
// Note that this has to be done separately since Completable doesn't have a parametrized
// type.
return CompletableHelper.createCallAdapter(scheduler);
}
CallAdapter<Observable<?>> callAdapter = getCallAdapter(returnType, scheduler);
if (isSingle) {
// Add Single-converter wrapper from a separate class. This defers classloading such that
// regular Observable operation can be leveraged without relying on this unstable RxJava API.
return SingleHelper.makeSingle(callAdapter);
}
return callAdapter;
}
private CallAdapter<Observable<?>> getCallAdapter(Type returnType, Scheduler scheduler) {
Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
Class<?> rawObservableType = getRawType(observableType);
if (rawObservableType == Response.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Response must be parameterized"
+ " as Response<Foo> or Response<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
return new ResponseCallAdapter(responseType, scheduler);
}
if (rawObservableType == Result.class) {
if (!(observableType instanceof ParameterizedType)) {
throw new IllegalStateException("Result must be parameterized"
+ " as Result<Foo> or Result<? extends Foo>");
}
Type responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
return new ResultCallAdapter(responseType, scheduler);
}
return new SimpleCallAdapter(observableType, scheduler);
}

这里我们看到,他这里做了一层封装,将适配器封装成CallAdapter>返回,这样便达到返回Observable对象的目的。

总结

我们将上面简单的回顾一下,这是一个建造适配器的工厂,在这个建造过程中,我们传入的东西是一样的,但是我们想得到不同的适配器,一个默认的适配器,一个响应在子线程的适配器,一个支持Rxjava的适配器,因此我们将get()方法抽象出来,只关注结果,而每一个不同的适配器由他自己的专门的工厂去实现,而我只需要通过工厂的get()方法去获得我想要的适配器就可以了,我们将Retrofit回调适配器相关的类用UML画出来看看

这里我们看出和设计模式中就比较像了,只不过设计模式UML中实现的是具体的产品类,而这里的产品则是一个接口类