當Android遇見工廠模式
我們先看一下一個Android系統應用中的工廠模式列子,再講解工廠模式。
package com.android.mms.ui;
import android.content.Context;
import android.util.Log;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import com.android.mms.model.Model;
/**
* The factory of concrete presenters.
*/
public class PresenterFactory {
private static final String TAG = "PresenterFactory";
private static final String PRESENTER_PACKAGE = "com.android.mms.ui.";
public static Presenter getPresenter(String className, Context context,
ViewInterface view, Model model) {
try {
if (className.indexOf(".") == -1) {
className = PRESENTER_PACKAGE + className;
}
Class c = Class.forName(className);
Constructor constructor = c.getConstructor(
Context.class, ViewInterface.class, Model.class);
return (Presenter) constructor.newInstance(context, view, model);
} catch (ClassNotFoundException e) {
Log.e(TAG, "Type not found: " + className, e);
} catch (NoSuchMethodException e) {
// Impossible to reach here.
Log.e(TAG, "No such constructor.", e);
} catch (InvocationTargetException e) {
Log.e(TAG, "Unexpected InvocationTargetException", e);
} catch (IllegalAccessException e) {
Log.e(TAG, "Unexpected IllegalAccessException", e);
} catch (InstantiationException e) {
Log.e(TAG, "Unexpected InstantiationException", e);
}
return null;
}
}
該程式碼來自於Android系統中的Mms模組Ui包下,為顯示縮圖的PresenterFactory,我們可以看到,使用了反射。
工廠設計模式在實際的開發中使用得非常多,我覺得已經學習過簡單的工廠模式(若沒學過,即A,B實現類,P為工廠類,通過傳入引數“A”,”B”,P裡面進行判斷,若是A就new A物件,若是B則new 一個B物件返回),通過簡單的工廠設計模式可以達到類的 解耦合目的,但是簡單工廠設計模式依然存在問題,我們不可能在設計工廠的時候,就知道我們以後要生成哪些類,那就是在增加一個子類時都需要修改工廠類,這樣很麻煩,而且那種,根據傳入引數進行判斷,從而自己new出不同的類的機制對於一個大型專案而言,是災難性的。
從簡單工廠模式中,對於實現類而言,的確是符合我們的開閉原則,當我們要新增新產品時,無需對業務進行修改,但是對於我們的工廠類而言,開閉原則沒有很好的體現,每次都得修改。
而,我們上面貼上的程式碼中,使用反射機制,這才是符合開閉原則的工廠模式。我們將類名當做引數傳入,這樣以後我們新建多少子類,都無需修改原來的程式碼。
軟體設計中,解耦一直是個大問題,也看到過一些C語言的專案,耦合度令人咂舌,而java中,其實很多的耦合性就是new,只要與new搭上關係,我們便造成了一個耦合。反射機制幫助我們很好的解決了這個問題,若對反射機制不懂,可以看我的上一篇java反射機制
我們進入正題:
- 定義
工廠方法模式-也我們所謂的工廠模式
定義一個用於建立物件的介面,讓其決定例項化哪個類
- 何時用到工廠模式
在前面已經大概說明了使用場景,總結就是在任何需要生產複雜物件的地方,都可以使用工廠模式,複雜物件適合使用工廠模式,用new就可以完成建立物件無需使用工廠模式。
通過使用工廠方法建立物件,我們可以避免客戶端程式碼依賴於它所使用的介面的具體實現。客戶端不再需要把物件建立的構造方法注入到自己的程式碼中去,客戶端只需要呼叫工廠,由工廠來決定符合要求的子類的建立過程。此外,工廠方法還可以滿足每次構造不同物件、物件的構造很複雜、物件的構造依賴具體環境等等需求。
- UML
- 注意
重回出發點,我們之所以採用工廠模式,是為了解耦,其實有時我們使用工廠模式的時候,一不小心就變成了抽象工廠模式,而對於抽象工廠模式,當減少一個方法使的提供的產品不再構成產品族之後,它就演變成了工廠方法模式。
而這一切,我覺得沒必要分的很清楚,我們只需要記住初衷,解耦。