1. 程式人生 > >Android 工廠模式

Android 工廠模式

1、什麼是工廠模式?

簡單來說他的字面意思:給外部批量提供相同或者不同的產品,而外部不需要關心工廠是如何建立一個複雜產品的過程。所以工廠模式可以降低模組間的耦合,同時可以提高擴充套件性(當有新的產品出現時,只需要擴充套件工廠就行了,上層模組不敏感)

工廠模式根據抽象的角度和層級的不同可以分為兩種模式:
1.工廠方法模式 (Factory Method)
2.抽象工廠模式 (Abstract Factory)

二、工廠方法模式的特點

一個抽象產品類(或介面),派生(或實現)多個真實產品類
一個抽象工廠類(或介面),派生(或實現)多個真實工廠類
一般來說標準的工廠方法模式需要一個工廠只生產一種產品,那麼當產品種類特別多的時候工廠的數量就特別多,所以通常會使用一些工廠方法模式的變種。

三、工廠方法模式的實現

(一)、工廠方法模式

1、標準工廠方法模式

首先先介紹一下標準的工廠方法模式,不帶任何的變種。以工廠生產不同作業系統的手機為例。建立一個產品介面,提供一個獲取系統資訊的方法。

public interface IPhone {  
    public void getOS();  
}  

再根據IPhone介面實現Android,IOS,Blackberry三種手機.

public class AndroidPhone implements IPhone {  
    private final String TAG = AndroidPhone.class.getSimpleName();  
    @Override
public void getOS() { Log.i(TAG, "im Android"); } } public class IosPhone implements IPhone { private final String TAG = IosPhone.class.getSimpleName(); @Override public void getOS() { Log.i(TAG, "im IOS"); } } public class BlackBerryPhone
implements IPhone {
private final String TAG = BlackBerryPhone.class.getSimpleName(); @Override public void getOS() { Log.i(TAG, "im BlackBerry"); } }

標準的工廠方法模式都需要有抽象的工廠介面或者基類.

public abstract class IGenerator {  
    public abstract IPhone generatePhone(String flag) throws Exception;  
}  

通過基類或者介面來實現真實的工廠類,這裡需要注意跟簡單工廠模式的不同,標準的工廠方法模式裡面一個工廠只生產一個產品,所以這裡要根據產品的種類劃分出來三個工廠,分別生產三種不同的產品。這種設計思想非常契合單一職責原則。

public class AndroidGenerator extends IGenerator {  
    @Override  
    public IPhone generatePhone() {  
        return new AndroidPhone();  
    }  
}  
public class IOSGenerator extends IGenerator {  
    @Override  
    public IPhone generatePhone() {  
        return new IosPhone();  
    }  
}  
public class BlackberryGenerator extends IGenerator {  
    @Override  
    public IPhone generatePhone() {  
        return new BlackBerryPhone();  
    }  
}  

在客戶端從工廠中獲得產品並使用的過程中都是通過介面進行訪問的,在建立產品的階段有效得降低了使用者和產品之間的耦合度。

public class Test{
    public static void main(String[] args){
        IGenerator androidGenerator = new AndroidGenerator();  
        IGenerator iosGenerator = new IOSGenerator();  
        IGenerator bbGenerator = new BlackberryGenerator();  
        IPhone android = androidGenerator.generatePhone();  
        IPhone ios = iosGenerator.generatePhone();  
        IPhone bb = bbGenerator.generatePhone();  
        android.getOS();  
        ios.getOS();  
        bb.getOS();  
    }
}

最終的執行效果顯而易見
im Android
im IOS
im BlackBerry

2、簡單工廠模式

接著分析一下簡單工廠模式,這是最簡單的變種,也叫做靜態工廠方法模式,從這個名字就可以看出工廠的方法是靜態的。既然工廠方法是靜態的,那麼工廠就不能通過繼承進行擴充套件,如果有新增的產品,就只能在靜態方法裡面做修改所以從這個角度來說簡單工廠模式是不符合開閉原則的。
因為這是靜態工廠方法模式,所以工廠類就沒有介面或者虛基類來提供抽象.通過不同的Flag來初始化不同的產品.

public class PhoneGenerator{  
    public final static String GENERATE_IOS = "generate_ios";  
    public final static String GENERATE_ANDROID = "generate_android";  
    public final static String GENERATE_BLACKBERRY = "generate_blackberry";  

    public static IPhone generatePhone(String flag) throws Exception {  
        IPhone iPhone = null;  
        switch (flag){  
            case GENERATE_ANDROID:  
                iPhone =  new AndroidPhone();  
                break;  
            case GENERATE_IOS:  
                iPhone =  new IosPhone();  
                break;  
            case GENERATE_BLACKBERRY:  
                iPhone =  new BlackBerryPhone();  
                break;  
            default:  
                throw new Exception("UNDEFINED FLAG");  
        }  
        return iPhone;  
    }  
}  

執行上面Test類,執行結果跟1的結果是一樣的。對外部來說要使用工廠只需要把目標產品類傳過去就行了。

3、結合反射的應用

假設需要加入一種搭載win10系統的手機,標準的工廠方法模式需要重新派生出來一個新的工廠來給客戶使用,簡單工廠模式也需要新增新的flag和case判斷去構造新的手機。有沒有什麼方法可以儘量避免這些修改呢?當然是有的,這裡可以通過使用Class.forName 反射的方式來達到目的。首先通過泛型來約束輸入輸出的引數型別,把異常拋到上層去處理並實現具體的工廠。

public abstract class IGenerator {  
    public abstract <T extends IPhone>T generatePhone(Class<T> clazz) throws Exception;  
}  
public class PhoneGenerator extends IGenerator {  
    public <T extends IPhone>T generatePhone(Class<T> clazz) throws Exception {  
        IPhone iPhone = null;  
        iPhone = (IPhone) Class.forName(clazz.getName()).newInstance();  
        return (T)iPhone;  
    }  
}  

通過這種裝載的方式去初始化產品就可以達到上面描述的需求,可以根據需求直接新增一個實現了IPhone介面的WindowsPhone產品而不需要修改工廠,客戶就可以直接從工廠拿到WindowsPhone的手機去使用了。

4、產品類私有構造應用

產品類私有構造應用其實更偏向與一種規範.既然使用工廠模式了,那就是這些手機全部都要在工廠內部創建出來。這種應用就做了限制,使用私有構造就不允許外部通過new的方式來建立,而工廠則通過反射和更改訪問許可權來建立產品。當然這個時候外部也可以通過同樣的方式來建立物件,所以說這個應用更偏向於一種團隊規範。

public class PhoneGenerator extends IGenerator {  
    public <T extends IPhone>T generatePhone(Class<T> clazz) throws Exception {  
        IPhone iPhone = null;  
        Class phone = Class.forName(clazz.getName());  
        phone.getDeclaredConstructor().setAccessible(true);  
        iPhone = (IPhone) phone.newInstance();  
        return (T)iPhone;  
    }  
}  

5、快取物件

對於那些建立起來特別消耗資源或者特別複雜的物件,可以使用下面的方式來進行一個長期的快取。對於那些有訪問數量需求的物件也可以建立快取List,通過設定最大建立數來控制物件量級的峰值。例如JDBC的最大連線數等.

public class PhoneGenerator extends IGenerator{  
    private Map<String, IPhone> map = new HashMap<>();  
    @Override  
    public <T extends IPhone> T generatePhone(Class<T> clazz) throws Exception{  
        IPhone iPhone = null;  
        if (map.containsKey(clazz.getName()))  
            iPhone = map.get(clazz.getName());  
        else {  
            iPhone = (IPhone) Class.forName(clazz.getName()).newInstance();  
            map.put(clazz.getName(), iPhone);  
        }  
        return (T) iPhone;  
    }  
}  

(二)、抽象工廠模式

抽象工廠模式的特點:

1、多個抽象產品類(或介面),派生(或實現)多個真實產品類
2、一個抽象工廠類(或介面),派生(或實現)多個真實工廠類
抽象工廠模式其實也算是工廠方法模式的一種延伸,在工廠方法模式中所有的產品都是一個系列的,都是從IPhone那裡實現出的不同真實產品,所以對於外部來說他們都是手機產品,只需要關心手機的抽象介面就行了。然而又多個業務種類,並且這些業務有些依賴關係的時候,這種情況下使用的工廠模式就是抽象工廠模式。
接著在抽象方法模式裡面的例子,在抽象工廠模式中我們需要再多開一種產品,那就平板吧,而平板又分為Android平板和iOS平板(這裡偷懶黑莓平板就不寫了),並且平板跟手機有很多共同的地方,例如相同的OS硬體設計等。既然是一個新的產品線了,那麼還是先抽象出來平板的介面來。還是老樣子,列印一下自己是什麼系統的。

public interface IPad {  
    public void getBrand();  
}  

接著通過IPad介面來實現兩個不同的平板.

public class AndroidPad implements IPad {  
    private final String TAG = AndroidPad.class.getSimpleName();  
    @Override  
    public void getBrand() {  
        Log.i(TAG, "im Android pad");  
    }  
}  
public class IOSPad implements IPad {  
    private final String TAG = IOSPad.class.getSimpleName();  
    @Override  
    public void getBrand() {  
        Log.i(TAG, "im IOS phone pad");  
    }  
}  

在抽象工廠的介面的時候還是繼續使用泛型來建立了,這樣也省的派生出來幾個不同的工廠。

public abstract class IGenerator {  
    public abstract <T extends IPhone>T generatePhone(Class<T> clazz) throws Exception;  
    public abstract <T extends IPad>T generatePad(Class<T> clazz) throws Exception;  
}  
public class ProductGenerator extends IGenerator{  
    @Override  
    public <T extends IPhone> T generatePhone(Class<T> clazz) throws Exception{  
        IPhone iPhone = (IPhone) Class.forName(clazz.getName()).newInstance();  
        return (T) iPhone;  
    }  

    @Override  
    public <T extends IPad> T generatePad(Class<T> clazz) throws Exception {  
        IPad iPad = (IPad) Class.forName(clazz.getName()).newInstance();  
        return (T) iPad;  
    }  
}  

假設有一個客戶需要來我廠定製移動產品,A套餐中包含一個IOS手機和一個Android的平板,B套餐中包含一個Android手機和一個IOS平板。而這個套餐規則可以通過工廠進行約束。這樣工廠就能勝任完成這個需求的任務了。
然而恰恰因為抽象工廠模式支援多種產品線,結果導致需要擴充套件一條新的產品的時候就會比較麻煩。假設需要新增一個螢幕貼膜產品,並且給每個出廠的帶螢幕的產品都配一個。那麼要做的修改不僅僅是要新增貼膜這個產品,還要修改從工廠的抽象到工廠的實現,還要修改工廠的約束。這是不符合開閉原則的。
但是如果只是擴充套件一個產品的子系列,例如要新增一個windows平板,抽象工廠模式和工廠方法模式一樣根本不需要修改工廠抽象和工廠實現,只需要新增產品就行了。

相關推薦

Android工廠模式

簡單記錄一下吧,比如現在有兩種方法可以完成一個功能,分別是MethodA和MethodB,這時我們可以新建一個工廠類MethodFactory,呼叫者只需要傳入一個type就可以實現這個功能,具體程式碼如下。 public class test { public st

Android 工廠模式,三種工廠模式的理解

工廠模式是一種建立者模式,在任何生成複雜物件的地方都可以使用工廠模式。理論來說在任何使用A a = new A()的方式都可以使用工廠模式,雖然使用工廠模式可能需要多做一些工作,但是在後續的開發和維護都帶來了方便。 如果我們需要在構建物件的時候,需要做很多的處

Android 工廠模式

1、什麼是工廠模式? 簡單來說他的字面意思:給外部批量提供相同或者不同的產品,而外部不需要關心工廠是如何建立一個複雜產品的過程。所以工廠模式可以降低模組間的耦合,同時可以提高擴充套件性(當有新的產品出現時,只需要擴充套件工廠就行了,上層模組不敏感) 工廠模式

Android 工廠模式

轉載地址:http://blog.csdn.net/beyond0525/article/details/22806393 在android中用到了很多的工廠類,如ThreadFactory建立抽象Runnable 。下面通過簡單的例子來學習工廠模式。 一、作用工廠模式(F

【設計模式Android】抽象工廠模式——嵌合體克隆工廠

設計模式 android 什麽是抽象工廠模式 所謂抽象工廠模式,就是為創建一組相關或者是互相依賴的對象提供一個接口,而不需要指定它們的具體類的設計模式。抽象工廠模式適用於一個對象族有相同的約束的情況,用不抽象的語言解釋就是國內著名開發者服務商環信在Android和iOS平臺都提供了IM SDK,盡管功

android設計模式——抽象工廠模式

定義:為建立一組相關或者是互相以來的物件提供一個介面,而不需要指定他們的具體的類, 使用場景: 在任何需要生成複雜物件的地方,都可以使用工廠方法模式. 應用舉例: 不同牌子的汽車工廠生產不同的汽車 類圖: AbstractFactory,抽象的工廠類 Concrete

android設計模式——工廠方法模式

定義:定義一個用於建立物件的介面,讓子類決定例項化哪個類. 使用場景: 在任何需要生成複雜物件的地方,都可以使用工廠方法模式. 應用舉例:去工廠提貨物,只需說要什麼貨,不必知道貨物是怎麼做出來的 類圖: Factory,抽象的工廠類 ConcreteFactory,具

Android 抽象工廠模式

文章目錄 1、抽象工廠模式介紹 2、抽象工廠模式的定義 3、抽象工廠模式的使用場景 4、抽象工廠模式的簡單實現 5、小結 1、抽象工廠模式

Android 工廠方法模式

文章目錄 1、工廠方法模式介紹 2、工廠方法模式的定義 3、使用場景 4、模式的簡單實現 1、工廠方法模式介紹 工廠方法模式(Factory Pa

Android 設計模式學習之工廠模式

蒐集的資料: http://blog.csdn.net/banketree/article/details/24985607  Android 設計模式 http://mobile.51cto.com/ahot-418968.htm   Android進階

移動開發之設計模式-工廠模式(IOS&Android)

資源 完全參照 工廠模式|菜鳥教程 ,但不包括IOS程式碼 工廠模式 工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。 在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是

移動開發之設計模式-抽象工廠模式(IOS&Android)

資源 完全參照 抽象工廠模式|菜鳥教程 ,但不包括IOS程式碼 抽象工廠模式 抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠建立其他工廠。該超級工廠又稱為其他工廠的工廠。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。 在抽象

Android設計模式之抽象工廠

抽象工廠模式的定義 為建立一組相關或者是相互依賴的物件提供一個介面,而不需要指定它們的具體類。 抽象工廠的使用場景 一個物件族有相同的約束時可以使用抽象工廠模式。舉個例子: Android、ios、window phone下都有簡訊軟體和撥號軟體,兩者都屬於軟體的範疇

Android設計模式之一個例子讓你徹底明白工廠模式(Factory Pattern)

提出疑問 這幾天研究工廠模式的時候,看到網上的一些文章中舉的例子我就很疑惑,我相信這也是許多人的疑惑:工廠模式的功能就是建立例項,我們建立例項直接new不就完了嗎,幹嘛還得再封裝一層工廠類,然後用工廠類再去new出這個例項?這不多此一舉嗎? 比如我看到這樣的

Android的設計模式-簡單工廠模式

前言 Android的設計模式系列文章介紹,歡迎關注,持續更新中: 1.定義 定義一個用於建立物件的介面,讓子類決定例項化哪個類。 2.介紹 簡單工廠模式屬於建立型模式。 簡單工廠模式又叫做靜態工廠方法模式。 3.UML類圖

Android中的工廠模式

什麼是工廠模式? 顧名思義,就是專門用來建立物件的工廠,這裡的物件指的是具有相同介面的類的物件。工廠模式可以決定將哪一個類進行例項化,不必事先知道每次要例項化的是哪一個類。 工廠模式有以下三種形態: 1、簡單工廠模式:又稱為靜態工廠方法模式。 2、工廠方

Android原始碼分析之簡單工廠模式

模式的定義 簡單工廠模式又稱為靜態方法工廠模式,是由一個工廠物件決定建立哪一個產品類的例項。 使用場景 客戶端需要建立物件、隱藏物件的建立過程,且目標物件型別數量不多的情況下,可以考慮使用簡單工廠模式。 UML類圖 角色介紹 Product 產品的通用介面,定義產

Android之大話設計模式--簡單工廠模式(靜態工廠方法模式)

簡單工廠模式解釋: 簡單工廠模式(Simple Factory Pattern)屬於類的創新型模式,又叫靜態工廠方法模式(Static Factory Method Pattern),是通過專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有相同的父親。 UML圖:

Android KK後為何工廠模式下無法adb 無法重啟機器 ?

為何工廠模式下無法adb reboot ? 正常情況下adb reboot 可以重啟, 其關鍵就是因為mediatek/config/{platform}factory_init.rc 中沒有定義 on property:sys.powerctl=*    powerctl ${sys.powerctl}

Android開發設計模式之——工廠模式

在android中用到了很多的工廠類,如ThreadFactory建立抽象Runnable 。下面通過簡單的例子來學習工廠模式。 一、作用工廠模式(Factory Method):定義一個用於建立物件的介面,讓子類決定將哪一個類例項化。從而使一個類的例項化延遲到其子類。 抽