Android設計模式之工廠模式 Factory
一.概述
平時做專案跟使用第三方類庫的時候經常會用到工廠模式.什麼是工廠模式,簡單來說就是他的字面意思.給外部批量提供相同或者不同的產品,而外部不需要關心工廠是如何建立一個複雜產品的過程.所以工廠模式可以降低模組間的耦合,同時可以提高擴充套件性(當有新的產品出現時,只需要擴充套件工廠就行了,上層模組不敏感).
工廠模式根據抽象的角度和層級的不同可以分為兩種模式:
1.工廠方法模式 (Factory Method)
2.抽象工廠模式 (Abstract Factory)
二.實現
1.工廠方法模式
工廠方法模式的特點是:
一個抽象產品類(或介面),派生(或實現)多個真實產品類
一個抽象工廠類(或介面),派生(或實現)多個真實工廠類
一般來說標準的工廠方法模式需要一個工廠只生產一種產品,那麼當產品種類特別多的時候工廠的數量就特別多,所以通常會使用一些工廠方法模式的變種.
1.)標準工廠方法模式
首先先介紹一下標準的工廠方法模式,不帶任何的變種.以工廠生產不同作業系統的手機為例.
建立一個產品介面,提供一個獲取系統資訊的方法.
/**
* Created by jesse on 15-8-17.
*/
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(); } }
IPhone android, ios, bb;
IGenerator androidGenerator, iosGenerator, bbGenerator;
androidGenerator = new AndroidGenerator();
iosGenerator = new IOSGenerator();
bbGenerator = new BlackberryGenerator();
android = androidGenerator.generatePhone();
ios = iosGenerator.generatePhone();
bb = bbGenerator.generatePhone();
android.getOS();
ios.getOS();
bb.getOS();
最終的執行效果顯而易見.
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;
}
}
對外部來說要使用工廠只需要把目標產品類傳過去就行了.執行結果跟1)中的是一樣的.
IPhone android, ios, bb;
android = PhoneGenerator.generatePhone(PhoneGenerator.GENERATE_ANDROID);
ios = PhoneGenerator.generatePhone(PhoneGenerator.GENERATE_IOS);
bb = PhoneGenerator.generatePhone(PhoneGenerator.GENERATE_BLACKBERRY);
android.getOS();
ios.getOS();
bb.getOS();
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;
}
}
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平板,抽象工廠模式和工廠方法模式一樣根本不需要修改工廠抽象和工廠實現,只需要新增產品就行了.
相關推薦
設計模式之工廠模式(Factory)在Android中的應用
1.工廠模式也是我們最常見的一種模式了,可以用來建立多個不同的例項物件。Android程式碼中最常見的應該是對Fragment的集中管理了。用Fragment工廠,創建出不同的fragment。 2.eg: 現在的app大多數都是由少數幾個activity和眾
Android設計模式之工廠模式 Factory
一.概述 平時做專案跟使用第三方類庫的時候經常會用到工廠模式.什麼是工廠模式,簡單來說就是他的字面意思.給外部批量提供相同或者不同的產品,而外部不需要關心工廠是如何建立一個複雜產品的過程.所以工廠模式可以降低模組間的耦合,同時可以提高擴充套件性(當有新的產品出
設計模式之工廠模式 Factory實現
aps 引擎 rac sed urn lose pla logs rgs simpleFactory //car接口 public interface Car { void run(); } //兩個實現類 public class Audi implemen
設計模式之工廠模式(Factory Pattern)
工廠模式在我們平時工作中還是非常常用的一種模式,它提供了一種建立物件的最佳方式。在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用一個共同的介面來指向新建立的物件。 工廠模式的定
JAVA設計模式之工廠模式—Factory Pattern
1.工廠模式簡介 工廠模式用於物件的建立,使得客戶從具體的產品物件中被解耦。 2.工廠模式分類 這裡以製造coffee的例子開始工廠模式設計之旅。 我們知道coffee只是一種泛舉,在點購咖啡時需要指定具體的咖啡種類:美式咖啡、卡布奇諾、拿鐵等等。 /** *
Android開發設計模式之——工廠模式
在android中用到了很多的工廠類,如ThreadFactory建立抽象Runnable 。下面通過簡單的例子來學習工廠模式。 一、作用工廠模式(Factory Method):定義一個用於建立物件的介面,讓子類決定將哪一個類例項化。從而使一個類的例項化延遲到其子類。 抽
Head First 設計模式之工廠模式(Factory Pattern)
前言: 除了使用new操作符之外,還有更多製造物件的方法。你將瞭解到例項化這個活動不應該總是公開的進行,也會意識到初始化會造成“耦合”的問題。工廠模式將會從複雜的依賴中幫你脫困。1. 簡單的工廠當看到“new”,就會想到“具體”,的確也是在例項化一個具體的類,而不
設計模式之工廠模式(Factory Pattern)
工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用一個共同的介面來指向新建立的物件。我這裡選擇生產手機的工廠作
Java[Android]設計模式之工廠模式(簡單工廠模式+工廠方法模式+抽象工廠模式)
1. 寫在前面 網上關於設計模式的文章已經非常詳盡了,寫這篇文章旨在給自己的學習做一個筆記和總結方便以後翻閱查詢,若對你有用可細學之若覺得膚淺可略之。 工廠模式屬於建立型設計模式,分為簡單工廠模式,工廠方法模式,抽象工廠模式三種,話不多說,請看下面一一道來。2. 簡單工廠
漫談設計模式之工廠模式
設計模式 策略模式 工廠模式 單例模式今天在這裏不過多介紹什麽是設計模式和為什麽要使用它?可以參考漫談設計模式之組合模式。一、什麽是抽象工廠設計模式? 一言以蔽之,抽象工廠就是用來創建功能相關的類,二、在什麽場景下使用它? 顧名思義,在我們的業務當中會有一種場景,有一個查詢頁面,上面有很多很多的查
淺析JAVA設計模式之工廠模式(二)
1.2 源碼 pub color post del tar pop south 1 工廠方法模式簡單介紹 工廠方法 (Factroy Method)模式:又稱多態性工廠模式(Polymorphic Factory),在這樣的模式中,核心工廠不再是一個詳
設計模式之工廠模式 (二)
height align sta sys 12px pack arrow nbsp 靈活 工廠模式分為三大類 簡單工廠(SimpleFactory)工廠方法模式(Factory Method) 抽象工廠模式(Abstract Factory)動態工廠(Dynamic
Java設計模式之工廠模式
href 1.2 net main override create 靜態工廠方法 lan soft 工廠方法模式 工廠方法模式分為三種:普通工廠模式、多個工廠方法模式和靜態工廠方法模式。 1、普通工廠模式 普通工廠模式就是建立一個工廠類,對實現了同一接口的一些類進行實
設計模式之工廠模式
一個 重要 沒有 告訴 統一 -s 還需 修改 span 大學學的最多的就是據結構和算法,不可否認,數據結構和算法非常重要,是編程的基石。但是在實際開發過程中,除非做的是比較底層的開發,否則的話,對設計模式的運用要比對數據結構和算法的運用要多。今天就來聊聊設計模式中的工廠模
設計模式之工廠模式類圖
工廠方法 png 工廠模式 src 設計模式 方法 .cn 技術分享 img 工廠模式:實例化對象,用工廠方法代替new操作 工廠模式包括工廠方法模式和抽象工廠模式 抽象工廠模式是工廠方法模式的擴展 實際應用舉例: 設計模式之工廠模式類圖
Java設計模式之工廠模式(二):抽象工廠模式
mar 模式 blank http left taxi ref www. app 2碳依5FVL冒傲3http://t.docin.com/etw488 am懦7鈉N山段9慌Q闌http://shequ.docin.com/ipu5657 iK1諾5N鍛認EUK剖嘲肆h
JAVA 設計模式 之 工廠模式
java 工廠模式 設計模式 1、為什麽要使用工廠模式? 比方說,一位滴滴司機,如果要去開車掙錢的話,他得自己會制造汽車,然後,才能使用汽車掙錢;對於這位司機來說,要求很高了,畢竟汽車很難制造出來; 如果使用工廠模式的話,這位司機,只需要知道汽車工廠就可以了,直接去工廠提車就行。從
23種設計模式之工廠模式
stream -a cdd 一個 sim ted bfd 變化 行為 披薩項目為例,使用工廠模式設計 需求:方便披薩品種擴展,便於維護,要能運行時擴展 披薩族(組)設計類圖 假設只有原料不同,其他操作如烘焙、切割、打包相同,就把prepare方法設置為抽象方法 一般設計如
PHP設計模式之工廠模式
interface () pub spa 設計 ace inter 接口 div <?php // 設計模式之工廠模式 class Factory { static public function fac ($id) { switch ($id)
JavaScript設計模式之工廠模式
無法 生產 什麽 接口 child ear 具體實現 bsp 常用 工廠模式是一種最常用的實例化對象模式,是用工廠方法代替new操作的一種模式。在工廠模式中,我們在創建對象時不會對客戶端暴露創建邏輯,並且是通過使用一個共同的接口來指向新創建的對象。因為工廠模式就相當於創建實