抽象工廠模式

參考:https://www.cnblogs.com/WindSun/p/10253248.html

模式動機

在工廠方法模式中具體工廠負責(zé)生產(chǎn)具體的產(chǎn)品卜高,每一個具體工廠對應(yīng)一種具體產(chǎn)品,工廠方法也具有唯一性南片,一般情況下掺涛,一個具體工廠中只有一個工廠方法或者一組重載的工廠方法。但是有時候我們需要一個工廠可以提供多個產(chǎn)品對象疼进,而不是單一的產(chǎn)品對象薪缆。

為了更清晰地理解工廠方法模式,需要先引入兩個概念:

? 產(chǎn)品等級結(jié)構(gòu):產(chǎn)品等級結(jié)構(gòu)即產(chǎn)品的繼承結(jié)構(gòu)伞广,如一個抽象類是電視機拣帽,其子類有海爾電視機、海信電視機嚼锄、TCL電視機减拭,則抽象電視機與具體品牌的電視機之間構(gòu)成了一個產(chǎn)品等級結(jié)構(gòu),抽象電視機是父類灾票,而具體品牌的電視機是其子類峡谊。

? 產(chǎn)品族:在抽象工廠模式中,產(chǎn)品族是指由同一個工廠生產(chǎn)的刊苍,位于不同產(chǎn)品等級結(jié)構(gòu)中的一組產(chǎn)品,如海爾電器工廠生產(chǎn)的海爾電視機濒析、海爾電冰箱正什,海爾電視機位于電視機產(chǎn)品等級結(jié)構(gòu)中,海爾電冰箱位于電冰箱產(chǎn)品等級結(jié)構(gòu)中号杏。

產(chǎn)品族與產(chǎn)品等級結(jié)構(gòu)示意圖:

當(dāng)系統(tǒng)所提供的工廠所需生產(chǎn)的具體產(chǎn)品并不是一個簡單的對象婴氮,而是多個位于不同產(chǎn)品等級結(jié)構(gòu)中屬于不同類型的具體產(chǎn)品時需要使用抽象工廠模式。

抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài)盾致。

抽象工廠模式與工廠方法模式最大的區(qū)別在于主经,工廠方法模式針對的是一個產(chǎn)品等級結(jié)構(gòu),而抽象工廠模式則需要面對多個產(chǎn)品等級結(jié)構(gòu)庭惜,一個工廠等級結(jié)構(gòu)可以負責(zé)多個不同產(chǎn)品等級結(jié)構(gòu)中的產(chǎn)品對象的創(chuàng)建 罩驻。當(dāng)一個工廠等級結(jié)構(gòu)可以創(chuàng)建出分屬于不同產(chǎn)品等級結(jié)構(gòu)的一個產(chǎn)品族中的所有對象時,抽象工廠模式比工廠方法模式更為簡單护赊、有效率惠遏。


模式定義

抽象工廠模式(Abstract Factory Pattern):提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口砾跃,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式节吮,屬于對象創(chuàng)建型模式抽高。

模式結(jié)構(gòu)

抽象工廠模式包含如下角色:

? AbstractFactory:抽象工廠

? ConcreteFactory:具體工廠

? AbstractProduct:抽象產(chǎn)品

? Product:具體產(chǎn)品

模式分析


抽象工廠類的典型代碼如下:

public abstract class AbstractFactory{
    public abstract AbstractProductA createProductA();
    public abstract AbstractProductB createProductB();
}

具體工廠類的典型代碼如下:

public class ConcreteFactory1 extends AbstractFactory
{
    public AbstractProductA createProductA()
    {
        return new ConcreteProductA1();
    }
    
    public AbstractProductB createProductB()
    {
        return new ConcreteProductB1();
    }
}

模式實例與解析

實例一:電器工廠

  • 一個電器工廠可以產(chǎn)生多種類型的電器,如海爾工廠可以生產(chǎn)海爾電視機透绩、海爾空調(diào)等翘骂,TCL工廠可以生產(chǎn)TCL電視機、TCL空調(diào)等帚豪,相同品牌的電器構(gòu)成一個產(chǎn)品族雏胃,而相同類型的電器構(gòu)成了一個產(chǎn)品等級結(jié)構(gòu),現(xiàn)使用抽象工廠模式模擬該場景志鞍。



    實例代碼(JAVA):

//抽象產(chǎn)品 Television
public interface Television
{
    public void play();
}

//具體產(chǎn)品 HaierTelevision
public class HaierTelevision implements Television
{
    public void play()
    {
        System.out.println("海爾電視機播放中......");
    }
}

//具體產(chǎn)品 TCLTelevision
public class TCLTelevision implements Television
{
    public void play()
    {
        System.out.println("TCL電視機播放中......");
    }
}

//抽象產(chǎn)品 AirConditioner
public interface AirConditioner
{
    public void changeTemperature();
}

//具體產(chǎn)品 HaierAirConditioner
public class HaierAirConditioner implements AirConditioner
{
    public void changeTemperature()
    {
        System.out.println("海爾空調(diào)溫度改變中......");
    }
}

//具體產(chǎn)品 TCLAirConditioner
public class TCLAirConditioner implements AirConditioner
{
    public void changeTemperature()
    {
        System.out.println("TCL空調(diào)溫度改變中......");
    }
}

//抽象工廠 EFactory
public interface EFactory
{
    public Television produceTelevision();
    public AirConditioner produceAirConditioner();
}

//具體工廠 HaierFactory
public class HaierFactory implements EFactory
{
    public Television produceTelevision()
    {
        return new HaierTelevision();
    }

    public AirConditioner produceAirConditioner()
    {
        return new HaierAirConditioner();
    }
}

//具體工廠 TCLFactory
public class TCLFactory implements EFactory
{
    public Television produceTelevision()
    {
        return new TCLTelevision();
    }

    public AirConditioner produceAirConditioner()
    {
        return new TCLAirConditioner();
    }
}

運行結(jié)果:


實例二:數(shù)據(jù)庫操作工廠

? 某系統(tǒng)為了改進數(shù)據(jù)庫操作的性能瞭亮,自定義數(shù)據(jù)庫連接對象Connection和語句對象Statement,可針對不同類型的數(shù)據(jù)庫提供不同的連接對象和語句對象固棚,如提供Oracle或SQL Server專用連接類和語句類统翩,而且用戶可以通過配置文件等方式根據(jù)實際需要動態(tài)更換系統(tǒng)數(shù)據(jù)庫。使用抽象工廠模式設(shè)計該系統(tǒng)此洲。


模式優(yōu)缺點

優(yōu)點

? 抽象工廠模式隔離了具體類的生成厂汗,使得客戶并不需要知道什么被創(chuàng)建。由于這種隔離呜师,更換一個具體工廠就變得相對容易娶桦。所有的具體工廠都實現(xiàn)了抽象工廠中定義的那些公共接口,因此只需改變具體工廠的實例汁汗,就可以在某種程度上改變整個軟件系統(tǒng)的行為衷畦。另外,應(yīng)用抽象工廠模式可以實現(xiàn)高內(nèi)聚低耦合的設(shè)計目的知牌,因此抽象工廠模式得到了廣泛的應(yīng)用祈争。

? 當(dāng)一個產(chǎn)品族中的多個對象被設(shè)計成一起工作時,它能夠保證客戶端始終只使用同一個產(chǎn)品族中的對象角寸。這對一些需要根據(jù)當(dāng)前環(huán)境來決定其行為的軟件系統(tǒng)來說菩混,是一種非常實用的設(shè)計模式。

? 增加新的具體工廠和產(chǎn)品族很方便扁藕,無須修改已有系統(tǒng)沮峡,符合“開閉原則”。

缺點

? 在添加新的產(chǎn)品對象時亿柑,難以擴展抽象工廠來生產(chǎn)新種類的產(chǎn)品邢疙,這是因為在抽象工廠角色中規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,要支持新種類的產(chǎn)品就意味著要對該接口進行擴展,而這將涉及到對抽象工廠角色及其所有子類的修改秘症,顯然會帶來較大的不便照卦。

? 開閉原則的傾斜性(增加新的工廠和產(chǎn)品族容易,增加新的產(chǎn)品等級結(jié)構(gòu)麻煩)

模式適用環(huán)境

在以下情況下可以使用抽象工廠模式:

? 一個系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實例如何被創(chuàng)建乡摹、組合和表達的細節(jié)役耕,這對于所有類型的工廠模式都是重要的。

? 系統(tǒng)中有多于一個的產(chǎn)品族聪廉,而每次只使用其中某一產(chǎn)品族瞬痘。

? 屬于同一個產(chǎn)品族的產(chǎn)品將在一起使用,這一約束必須在系統(tǒng)的設(shè)計中體現(xiàn)出來板熊。

? 系統(tǒng)提供一個產(chǎn)品類的庫框全,所有的產(chǎn)品以同樣的接口出現(xiàn),從而使客戶端不依賴于具體實現(xiàn)干签。

模式應(yīng)用

(1) Java SE AWT(抽象窗口工具包)

Java語言的AWT(抽象窗口工具包)中就使用了抽象工廠模式津辩,它使用抽象工廠模式來實現(xiàn)在不同的操作系統(tǒng)中應(yīng)用程序呈現(xiàn)與所在操作系統(tǒng)一致的外觀界面。

(2) 在很多軟件系統(tǒng)中需要更換界面主題容劳,要求界面中的按鈕喘沿、文本框、背景色等一起發(fā)生改變時竭贩,可以使用抽象工廠模式進行設(shè)計蚜印。

模式擴展

“開閉原則”的傾斜性

“開閉原則”要求系統(tǒng)對擴展開放,對修改封閉留量,通過擴展達到增強其功能的目的窄赋。對于涉及到多個產(chǎn)品族與多個產(chǎn)品等級結(jié)構(gòu)的系統(tǒng),其功能增強包括兩方面:

(1) 增加產(chǎn)品族:對于增加新的產(chǎn)品族楼熄,工廠方法模式很好的支持了“開閉原則”忆绰,對于新增加的產(chǎn)品族,只需要對應(yīng)增加一個新的具體工廠即可孝赫,對已有代碼無須做任何修改较木。

(2) 增加新的產(chǎn)品等級結(jié)構(gòu):對于增加新的產(chǎn)品等級結(jié)構(gòu),需要修改所有的工廠角色青柄,包括抽象工廠類,在所有的工廠類中都需要增加生產(chǎn)新產(chǎn)品的方法预侯,不能很好地支持“開閉原則”致开。

抽象工廠模式的這種性質(zhì)稱為“開閉原則”的傾斜性,抽象工廠模式以一種傾斜的方式支持增加新的產(chǎn)品萎馅,它為新產(chǎn)品族的增加提供方便双戳,但不能為新的產(chǎn)品等級結(jié)構(gòu)的增加提供這樣的方便。

工廠模式的退化

當(dāng)抽象工廠模式中每一個具體工廠類只創(chuàng)建一個產(chǎn)品對象糜芳,也就是只存在一個產(chǎn)品等級結(jié)構(gòu)時飒货,抽象工廠模式退化成工廠方法模式魄衅;當(dāng)工廠方法模式中抽象工廠與具體工廠合并,提供一個統(tǒng)一的工廠來創(chuàng)建產(chǎn)品對象塘辅,并將創(chuàng)建對象的工廠方法設(shè)計為靜態(tài)方法時晃虫,工廠方法模式退化成簡單工廠模式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末扣墩,一起剝皮案震驚了整個濱河市哲银,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌呻惕,老刑警劉巖荆责,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異亚脆,居然都是意外死亡做院,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門濒持,熙熙樓的掌柜王于貴愁眉苦臉地迎上來键耕,“玉大人,你說我怎么就攤上這事弥喉∮艟梗” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵由境,是天一觀的道長棚亩。 經(jīng)常有香客問我,道長虏杰,這世上最難降的妖魔是什么讥蟆? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮纺阔,結(jié)果婚禮上瘸彤,老公的妹妹穿的比我還像新娘。我一直安慰自己笛钝,他們只是感情好质况,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玻靡,像睡著了一般结榄。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上囤捻,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天臼朗,我揣著相機與錄音,去河邊找鬼。 笑死视哑,一個胖子當(dāng)著我的面吹牛绣否,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挡毅,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蒜撮,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了慷嗜?” 一聲冷哼從身側(cè)響起淀弹,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎庆械,沒想到半個月后薇溃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡缭乘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年沐序,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片堕绩。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡策幼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奴紧,到底是詐尸還是另有隱情特姐,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布黍氮,位于F島的核電站唐含,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沫浆。R本人自食惡果不足惜捷枯,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望专执。 院中可真熱鬧淮捆,春花似錦、人聲如沸本股。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽拄显。三九已至蚕苇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凿叠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盒件,地道東北人蹬碧。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像炒刁,于是被迫代替她去往敵國和親恩沽。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354