1. 程式人生 > >當Android遇見工廠模式

當Android遇見工廠模式

設計模式.png
我們先看一下一個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

工廠模式.png

  • 注意
    重回出發點,我們之所以採用工廠模式,是為了解耦,其實有時我們使用工廠模式的時候,一不小心就變成了抽象工廠模式,而對於抽象工廠模式,當減少一個方法使的提供的產品不再構成產品族之後,它就演變成了工廠方法模式。
    而這一切,我覺得沒必要分的很清楚,我們只需要記住初衷,解耦。