Android編程設(shè)計模式之抽象工廠模式詳解
本文實例講述了Android編程設(shè)計模式之抽象工廠模式。分享給大家供大家參考,具體如下:
一、介紹
抽象工廠模式(Abstract Factory Pattern),也是創(chuàng)建型設(shè)計模式之一。前一節(jié)我們已經(jīng)了解了工廠方法模式,那么這個抽象工廠又是怎么一回事呢?大家聯(lián)想一下現(xiàn)實生活中的工廠肯定都是具體的,也就是說每個工廠都會生產(chǎn)某一種具體的產(chǎn)品,那么抽象工廠意味著生產(chǎn)出來的產(chǎn)品是不確定的,那這豈不是很奇怪?抽象工廠模式起源于以前對不同操作系統(tǒng)的圖形化解決方案,如不同操作系統(tǒng)中的按鈕和文本框控件其實現(xiàn)不同,展示效果也不一樣,對于每一個操作系統(tǒng),其本身就構(gòu)成一個產(chǎn)品類,而按鈕與文本框控件也構(gòu)成一個產(chǎn)品類,兩種產(chǎn)品類兩種變化,各自有自己的特性,如Android中的Button和TextView,iOS中的Button和TextView,Window Phone中的Button和TextView等。
二、定義
為創(chuàng)建一組相關(guān)或者是相互依賴的對象提供一個接口,而不需要指定它們的具體類。
三、使用場景
一個對象族有相同的約束時可以使用抽象工廠模式。是不是聽起來很抽象?舉個例子,Android、iOS、Window Phone下都有短信軟件和撥號軟件,兩者都屬于Software軟件的范疇,但是,它們所在的操作系統(tǒng)平臺不一樣,即便是同一家公司出品的軟件,其代碼的實現(xiàn)邏輯也是不一樣的,這時候就可以考慮使用抽象工廠方法模式來產(chǎn)生Android、iOS、Window Phone下的短信軟件和撥號軟件。
四、抽象工廠模式的UML類圖
UML類圖:

雖然抽象工廠方法模式的種類繁多,但是,主要還是分為4類:
AbstractFactory:抽象工廠角色,它聲明了一組用于創(chuàng)建一種產(chǎn)品的方法,每一個方法對應(yīng)一種產(chǎn)品。
ConcreteFactory:具體的工廠角色,它實現(xiàn)了在抽象工廠中定義的創(chuàng)建產(chǎn)品的方法,生成一組具體產(chǎn)品,這些產(chǎn)品構(gòu)成了一個產(chǎn)品種類,每一個產(chǎn)品都位于某個產(chǎn)品等級結(jié)構(gòu)中。
AbstractProduct:抽象產(chǎn)品角色,它為每種產(chǎn)品聲明接口。
ConcreteProduct:具體產(chǎn)品角色,它定義具體工廠生產(chǎn)的具體產(chǎn)品對象,實現(xiàn)抽象產(chǎn)品接口中聲明的業(yè)務(wù)方法。
五、簡單實現(xiàn)
以車廠生產(chǎn)汽車零部件為例,A、B兩家車廠分別生產(chǎn)不同的輪胎、發(fā)動機(jī)、制動系統(tǒng)。雖然生產(chǎn)的零件不同,型號不同。但是根本上都有共同的約束,就是輪胎、發(fā)動機(jī)、制動系統(tǒng)。
輪胎相關(guān)類:
public interface ITire {
/**
* 輪胎
*/
void tire();
}
public class NormalTire implements ITire{
@Override
public void tire() {
System.out.println("普通輪胎");
}
}
public class SUVTire implements ITire{
@Override
public void tire() {
System.out.println("越野輪胎");
}
}
發(fā)動機(jī)相關(guān)類:
public interface IEngine {
/**
*發(fā)動機(jī)
*/
void engine();
}
public class DomesticEngine implements IEngine{
@Override
public void engine() {
System.out.println("國產(chǎn)發(fā)動機(jī)");
}
}
public class ImportEngine implements IEngine{
@Override
public void engine() {
System.out.println("進(jìn)口發(fā)動機(jī)");
}
}
制動系統(tǒng)相關(guān)類:
public interface IBrake {
/**
*制動系統(tǒng)
*/
void brake();
}
public class NormalBrake implements IBrake{
@Override
public void brake() {
System.out.println("普通制動");
}
}
public class SeniorBrake implements IBrake{
@Override
public void brake() {
System.out.println("高級制動");
}
}
抽象車廠類:
public abstract class CarFactory {
/**
* 生產(chǎn)輪胎
*
* @return 輪胎
* */
public abstract ITire createTire();
/**
* 生產(chǎn)發(fā)動機(jī)
*
* @return 發(fā)動機(jī)
* */
public abstract IEngine createEngine();
/**
* 生產(chǎn)制動系統(tǒng)
*
* @return 制動系統(tǒng)
* */
public abstract IBrake createBrake();
}
A車廠:
public class AFactory extends CarFactory{
@Override
public ITire createTire() {
return new NormalTire();
}
@Override
public IEngine createEngine() {
return new DomesticEngine();
}
@Override
public IBrake createBrake() {
return new NormalBrake();
}
}
B車廠:
public class BFactory extends CarFactory{
@Override
public ITire createTire() {
return new SUVTire();
}
@Override
public IEngine createEngine() {
return new ImportEngine();
}
@Override
public IBrake createBrake() {
return new SeniorBrake();
}
}
客戶類:
public class Client {
public static void main(String[] args) {
//A車廠
CarFactory factoryA = new AFactory();
factoryA.createTire().tire();
factoryA.createEngine().engine();
factoryA.createBrake().brake();
System.out.println("---------------");
//B車廠
CarFactory factoryB = new BFactory();
factoryB.createTire().tire();
factoryB.createEngine().engine();
factoryB.createBrake().brake();
}
}
結(jié)果:
普通輪胎 國產(chǎn)發(fā)動機(jī) 普通制動 ------------------ 越野輪胎 進(jìn)口發(fā)動機(jī) 高級制動
可以看出上面模擬了兩個車廠,如果有了C廠、D廠,各自廠家生產(chǎn)的零部件型號種類又不相同,那么我們創(chuàng)建的類文件就會翻倍。這也是抽象工廠模式的一個弊端,所以實際開發(fā)中要權(quán)衡使用。
六、與工廠方法模式的區(qū)別
上一節(jié)有介紹了工廠方法模式,那么他們的區(qū)別是什么?抽象工廠模式是工廠方法模式的升級版本。對比如下:
| 工廠方法模式 | 抽象工廠模式 |
|---|---|
| 只有一個抽象產(chǎn)品類 | 有多個抽象產(chǎn)品類 |
| 具體工廠類只能創(chuàng)建一個具體產(chǎn)品類的實例 | 抽象工廠類能創(chuàng)建多個具體產(chǎn)品類的實例 |
七、源碼中的實現(xiàn)
抽象工廠模式在Android源碼中使用較少,因為很少會出現(xiàn)多個產(chǎn)品種類的情況,大部分使用工廠方法模式即可解決。
MediaPlayer
MediaPlayer Factory分別會生成4個不同的MediaPlayer基類:StagefrightPlayer、NuPlayerDriver、MidiFile和TestPlayerStub,四者均繼承于MediaPlayerBase。
八、總結(jié)
優(yōu)點(diǎn):
分離接口與實現(xiàn),客戶端使用抽象工廠來創(chuàng)建需要的對象,而客戶端根本就不知道具體的實現(xiàn)是誰,客戶端只是面向產(chǎn)品的接口編程而已,使其從具體的產(chǎn)品實現(xiàn)中解耦,同時基于接口與實現(xiàn)分離,使抽象該工廠方法模式在切換產(chǎn)品類時更加靈活、容易。
缺點(diǎn):
一是對類文件的爆炸性增加
二是不太容易擴(kuò)展新的產(chǎn)品類
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對大家Android程序設(shè)計有所幫助。
相關(guān)文章
Android ViewPager實現(xiàn)Banner循環(huán)播放
這篇文章主要為大家詳細(xì)介紹了Android ViewPager實現(xiàn)Banner循環(huán)播放,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-09-09
Android判斷后臺服務(wù)是否開啟的兩種方法實例詳解
這篇文章主要介紹了Android判斷后臺服務(wù)是否開啟的方法的相關(guān)資料,這里提供了兩種方法及實例,需要的朋友可以參考下2017-07-07
Android M(6.x)使用OkHttp包解析和發(fā)送JSON請求的教程
Android 6.0采用的SPDY支持HTTP上GZIP壓縮的傳輸,這使得OkHttp包的功能能夠進(jìn)一步被利用,本文我們來總結(jié)一下Android M(6.0)使用OkHttp包解析和發(fā)送JSON請求的教程2016-07-07
Android EditText 監(jiān)聽用戶輸入完成的實例
下面小編就為大家分享一篇Android EditText 監(jiān)聽用戶輸入完成的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02
Android 判斷當(dāng)前語言環(huán)境是否是中文環(huán)境
本文主要介紹了Android 判斷當(dāng)前語言環(huán)境是否是中文環(huán)境的方法。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04
清楚詳解Android?進(jìn)程間圖傳遞圖形buffer原理
這篇文章主要為大家清楚的詳解了Android?進(jìn)程間圖傳遞圖形buffer原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Android Secret Code(輸入字符彈出手機(jī)信息)詳解
這篇文章主要介紹了Android Secret Code(輸入字符彈出手機(jī)信息)詳解的相關(guān)資料,需要的朋友可以參考下2016-11-11

