淺談設(shè)計(jì)模式之抽象工廠模式

抽象工廠模式(Abstract factory pattern)

抽象工廠模式(Abstract factory pattern)是一種軟件開發(fā)設(shè)計(jì)模式粟耻。抽象工廠模式提供了一種方式,可以將一組具有同一主題的單獨(dú)的工廠封裝起來。在正常使用中,客戶端程序需要?jiǎng)?chuàng)建抽象工廠的具體實(shí)現(xiàn)跨释,然后使用抽象工廠作為接口來創(chuàng)建這一主題的具體對(duì)象官地〉薅恚客戶端程序不需要知道(或關(guān)心)它從這些內(nèi)部的工廠方法中獲得對(duì)象的具體類型疗绣,因?yàn)榭蛻舳顺绦騼H使用這些對(duì)象的通用接口线召。抽象工廠模式將一組對(duì)象的實(shí)現(xiàn)細(xì)節(jié)與他們的一般使用分離開來。

定義:為創(chuàng)建一組相關(guān)或相互依賴的對(duì)象提供一個(gè)接口多矮,而且無需指定他們的具體類缓淹。

類型:創(chuàng)建類模式

類圖:

UML

GuiFactory接口中的createButton方法返回Button類型的對(duì)象。返回Button的哪種實(shí)現(xiàn)依賴于使用GuiFactory的哪種實(shí)現(xiàn)工窍。

需要注意的是割卖,為了簡(jiǎn)潔起見,以上類圖僅僅展示了創(chuàng)建一個(gè)類型對(duì)象的工廠患雏。而在抽象工廠模式中鹏溯,通常一個(gè)工廠能夠創(chuàng)建若干種不同類型的對(duì)象。


產(chǎn)品族

先來認(rèn)識(shí)下什么是產(chǎn)品族:位于不同產(chǎn)品等級(jí)結(jié)構(gòu)中淹仑,功能相關(guān)聯(lián)的產(chǎn)品組成的家族丙挽。還是讓我們換一個(gè)例子來形象地說明一下吧。

產(chǎn)品族

圖中的BmwCarBenzCar就是兩個(gè)產(chǎn)品樹(產(chǎn)品層次結(jié)構(gòu))匀借;而如圖所示的BenzSportsCarBmwSportsCar就是一個(gè)產(chǎn)品族颜阐。他們都可以放到跑車家族中,因此功能有所關(guān)聯(lián)吓肋。同理BmwBussinessCarBenzSportsCar也是一個(gè)產(chǎn)品族凳怨。


回到抽象工廠模式的話題上。

可以說是鬼,抽象工廠模式和工廠方法模式的區(qū)別就在于需要?jiǎng)?chuàng)建對(duì)象的復(fù)雜程度上肤舞。而且抽象工廠模式是三個(gè)里面最為抽象、最具一般性的均蜜。

抽象工廠模式的用意為:給客戶端提供一個(gè)接口李剖,可以創(chuàng)建多個(gè)產(chǎn)品族中的產(chǎn)品對(duì)象。

而且使用抽象工廠模式還要滿足一下條件:

  1. 系統(tǒng)中有多個(gè)產(chǎn)品族囤耳,而系統(tǒng)一次只可能消費(fèi)其中一族產(chǎn)品篙顺。
  1. 同屬于同一個(gè)產(chǎn)品族的產(chǎn)品以其使用。

來看看抽象工廠模式的各個(gè)角色(和工廠方法的如出一轍):

  1. 抽象工廠角色: 這是工廠方法模式的核心充择,它與應(yīng)用程序無關(guān)德玫。是具體工廠角色必須實(shí)現(xiàn)的接口或者必須繼承的父類。在java中它由抽象類或者接口來實(shí)現(xiàn)聪铺。
  1. 具體工廠角色:它含有和具體業(yè)務(wù)邏輯有關(guān)的代碼化焕。由應(yīng)用程序調(diào)用以創(chuàng)建對(duì)應(yīng)的具體產(chǎn)品的對(duì)象。在java中它由具體的類來實(shí)現(xiàn)铃剔。
  1. 抽象產(chǎn)品角色:它是具體產(chǎn)品繼承的父類或者是實(shí)現(xiàn)的接口撒桨。在java中一般有抽象類或者接口來實(shí)現(xiàn)。
  1. 具體產(chǎn)品角色:具體工廠角色所創(chuàng)建的對(duì)象就是此角色的實(shí)例键兜。在java中由具體的類來實(shí)現(xiàn)凤类。

類圖如下:


抽象工廠模式

代碼舉例

// 產(chǎn)品 Plant接口    
public interface Plant { }//標(biāo)志接口  

//具體產(chǎn)品PlantA,PlantB    
public class PlantA implements Plant {    
  
    public PlantA () {    
        System.out.println("create PlantA !");    
    }    
  
    public void doSomething() {    
        System.out.println(" PlantA do something ...");    
    }    
}    
public class PlantB implements Plant {    
    public PlantB () {    
        System.out.println("create PlantB !");    
    }    
  
    public void doSomething() {    
        System.out.println(" PlantB do something ...");    
    }    
}   
 
//產(chǎn)品Fruit接口    
public interface Fruit { }    

//具體產(chǎn)品FruitA普气,F(xiàn)ruitB    
public class FruitA implements Fruit {    
    public FruitA() {    
        System.out.println("create FruitA !");    
    }    
    public void doSomething() {    
        System.out.println(" FruitA do something ...");    
    }    
}    
public class FruitB implements Fruit {    
    public FruitB() {    
        System.out.println("create FruitB !");    
    }    
    public void doSomething() {    
        System.out.println(" FruitB do something ...");    
    }    
}    

//抽象工廠方法    
public interface AbstractFactory {    
    public Plant createPlant();    
    public Fruit createFruit();    
}    

//具體工廠方法    
public class FactoryA implements AbstractFactory {    
    public Plant createPlant() {    
        return new PlantA();    
    }    
    public Fruit createFruit() {    
        return new FruitA();    
    }    
}    
public class FactoryB implements AbstractFactory {    
    public Plant createPlant() {    
        return new PlantB();    
    }    
    public Fruit createFruit() {    
        return new FruitB();    
    }    
}   
//調(diào)用工廠方法   
public class Client {   
    public void method1() {   
        AbstractFactory instance = new FactoryA();   
        instance.createPlant();   
    }   
}

建議可以看看GoF的《設(shè)計(jì)模式》一書谜疤,里面說到工廠模式時(shí)舉得例子淺顯易懂。


工廠方法模式與抽象工廠模式的區(qū)別

可以這么說现诀,工廠方法模式是一種極端情況的抽象工廠模式夷磕,而抽象工廠模式可以看成是工廠方法模式的一種推廣。

  1. 其實(shí)工廠方法模式是用來創(chuàng)建一個(gè)產(chǎn)品的等級(jí)結(jié)構(gòu)的仔沿,而抽象工廠模式是用來創(chuàng)建多個(gè)產(chǎn)品的等級(jí)結(jié)構(gòu)的坐桩。工廠方法創(chuàng)建一般只有一個(gè)方法,創(chuàng)建一種產(chǎn)品封锉。抽象工廠一般有多個(gè)方法绵跷,創(chuàng)建一系列產(chǎn)品。

  2. 工廠方法模式只有一個(gè)抽象產(chǎn)品類成福,而抽象工廠模式有多個(gè)碾局。工廠方法模式的具體工廠類只能創(chuàng)建一個(gè)具體產(chǎn)品類的實(shí)例,而抽象工廠模式可以創(chuàng)建多個(gè)奴艾。

簡(jiǎn)而言之净当,
工廠方法模式:

  • 一個(gè)抽象產(chǎn)品類,可以派生出多個(gè)具體產(chǎn)品類蕴潦。
  • 一個(gè)抽象工廠類像啼,可以派生出多個(gè)具體工廠類。
  • 每個(gè)具體工廠類只能創(chuàng)建一個(gè)具體產(chǎn)品類的實(shí)例品擎。

抽象工廠模式:

  • 多個(gè)抽象產(chǎn)品類埋合,每個(gè)抽象產(chǎn)品類可以派生出多個(gè)具體產(chǎn)品類。
  • 一個(gè)抽象工廠類萄传,可以派生出多個(gè)具體工廠類甚颂。
  • 每個(gè)具體工廠類可以創(chuàng)建多個(gè)具體產(chǎn)品類的實(shí)例。

適用性

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

  • 一個(gè)系統(tǒng)要獨(dú)立于它的產(chǎn)品的創(chuàng)建秀菱、組合和表示時(shí)振诬。
  • 一個(gè)系統(tǒng)要由多個(gè)產(chǎn)品系列中的一個(gè)來配置時(shí)。
  • 需要強(qiáng)調(diào)一系列相關(guān)的產(chǎn)品對(duì)象的設(shè)計(jì)以便進(jìn)行聯(lián)合使用時(shí)衍菱。
  • 提供一個(gè)產(chǎn)品類庫赶么,而只想顯示它們的接口而不是實(shí)現(xiàn)時(shí)。

優(yōu)點(diǎn)

  • 具體產(chǎn)品從客戶代碼中被分離出來脊串。
  • 容易改變產(chǎn)品的系列辫呻。
  • 將一個(gè)系列的產(chǎn)品族統(tǒng)一到一起創(chuàng)建清钥。

缺點(diǎn)

  • 在產(chǎn)品族中擴(kuò)展新的產(chǎn)品是很困難的,它需要修改抽象工廠的接口

參考資料:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末放闺,一起剝皮案震驚了整個(gè)濱河市祟昭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怖侦,老刑警劉巖篡悟,帶你破解...
    沈念sama閱讀 222,378評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異匾寝,居然都是意外死亡搬葬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門艳悔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來急凰,“玉大人,你說我怎么就攤上這事很钓∠愀” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵码倦,是天一觀的道長(zhǎng)企孩。 經(jīng)常有香客問我,道長(zhǎng)袁稽,這世上最難降的妖魔是什么勿璃? 我笑而不...
    開封第一講書人閱讀 59,938評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮推汽,結(jié)果婚禮上补疑,老公的妹妹穿的比我還像新娘。我一直安慰自己歹撒,他們只是感情好莲组,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,955評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著暖夭,像睡著了一般锹杈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上迈着,一...
    開封第一講書人閱讀 52,549評(píng)論 1 312
  • 那天竭望,我揣著相機(jī)與錄音,去河邊找鬼裕菠。 笑死咬清,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播旧烧,決...
    沈念sama閱讀 41,063評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼影钉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了粪滤?” 一聲冷哼從身側(cè)響起斧拍,我...
    開封第一講書人閱讀 39,991評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤雀扶,失蹤者是張志新(化名)和其女友劉穎杖小,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體愚墓,經(jīng)...
    沈念sama閱讀 46,522評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡予权,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,604評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浪册。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扫腺。...
    茶點(diǎn)故事閱讀 40,742評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖村象,靈堂內(nèi)的尸體忽然破棺而出笆环,到底是詐尸還是另有隱情,我是刑警寧澤厚者,帶...
    沈念sama閱讀 36,413評(píng)論 5 351
  • 正文 年R本政府宣布躁劣,位于F島的核電站,受9級(jí)特大地震影響库菲,放射性物質(zhì)發(fā)生泄漏账忘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,094評(píng)論 3 335
  • 文/蒙蒙 一熙宇、第九天 我趴在偏房一處隱蔽的房頂上張望鳖擒。 院中可真熱鬧,春花似錦烫止、人聲如沸蒋荚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽期升。三九已至,卻和暖如春荆几,著一層夾襖步出監(jiān)牢的瞬間吓妆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評(píng)論 1 274
  • 我被黑心中介騙來泰國打工吨铸, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留行拢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,159評(píng)論 3 378
  • 正文 我出身青樓诞吱,卻偏偏與公主長(zhǎng)得像舟奠,于是被迫代替她去往敵國和親竭缝。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,747評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容