創(chuàng)建型模式 - 抽象工廠模式

0x01 前言

??繼上一篇文章所述,抽象工廠模式(Abstract Factory Pattern)是圍繞一個超級工廠創(chuàng)建其他工廠降传。該超級工廠又稱為其他工廠的工廠篷朵。這種類型的設(shè)計模式屬于創(chuàng)建型模式,它提供了一種創(chuàng)建對象的最佳方式婆排。

??在抽象工廠模式中声旺,接口是負(fù)責(zé)創(chuàng)建一個相關(guān)對象的工廠,不需要顯式指定它們的類段只。每個生成的工廠都能按照工廠模式提供對象腮猖。

0x02 簡介

意圖:提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口,而無需指定它們具體的類赞枕。

主要解決:主要解決接口選擇的問題澈缺。

何時使用:系統(tǒng)的產(chǎn)品有多于一個的產(chǎn)品族坪创,而系統(tǒng)只消費(fèi)其中某一族的產(chǎn)品。

如何解決:在一個產(chǎn)品族里面姐赡,定義多個產(chǎn)品误堡。

關(guān)鍵代碼:在一個工廠里聚合多個同類產(chǎn)品。

應(yīng)用實(shí)例:工作了雏吭,為了參加一些聚會锁施,肯定有兩套或多套衣服吧,比如說有商務(wù)裝(成套杖们,一系列具體產(chǎn)品)悉抵、時尚裝(成套,一系列具體產(chǎn)品)摘完,甚至對于一個家庭來說姥饰,可能有商務(wù)女裝、商務(wù)男裝孝治、時尚女裝列粪、時尚男裝,這些也都是成套的谈飒,即一系列具體產(chǎn)品岂座。假設(shè)一種情況(現(xiàn)實(shí)中是不存在的,要不然杭措,沒法進(jìn)入共產(chǎn)主義了费什,但有利于說明抽象工廠模式),在您的家中手素,某一個衣柜(具體工廠)只能存放某一種這樣的衣服(成套鸳址,一系列具體產(chǎn)品),每次拿這種成套的衣服時也自然要從這個衣柜中取出了泉懦。用 OO 的思想(面向?qū)ο螅┤ダ斫飧迨颍械囊鹿瘢ň唧w工廠)都是衣柜類的(抽象工廠)某一個,而每一件成套的衣服又包括具體的上衣(某一具體產(chǎn)品)崩哩,褲子(某一具體產(chǎn)品)巡球,這些具體的上衣其實(shí)也都是上衣(抽象產(chǎn)品),具體的褲子也都是褲子(另一個抽象產(chǎn)品)琢锋。

優(yōu)點(diǎn):當(dāng)一個產(chǎn)品族中的多個對象被設(shè)計成一起工作時辕漂,它能保證客戶端始終只使用同一個產(chǎn)品族中的對象呢灶。

缺點(diǎn):產(chǎn)品族擴(kuò)展非常困難吴超,要增加一個系列的某一產(chǎn)品,既要在抽象的 Creator 里加代碼鸯乃,又要在具體的里面加代碼鲸阻。

使用場景: 1跋涣、QQ 換皮膚,一整套一起換鸟悴。 2陈辱、生成不同操作系統(tǒng)的程序。

注意事項(xiàng):產(chǎn)品族難擴(kuò)展细诸,產(chǎn)品等級易擴(kuò)展沛贪。

0x03 設(shè)計概述

??抽象工廠模式是工廠方法模式的升級版本,他用來創(chuàng)建一組相關(guān)或者相互依賴的對象震贵。

??抽象工廠模式時代:隨著客戶的要求越來越高利赋,需要定制不同組合的電腦。例如聯(lián)想 Y 系列猩系,華碩 G 系列媚送,聯(lián)想 Y 配備性能級顯卡,聯(lián)想 G 配備發(fā)燒級顯卡寇甸。那么并不需要創(chuàng)辦一個生產(chǎn)聯(lián)想 Y 性能級顯卡電腦的工廠塘偎、華碩 G 發(fā)燒級顯卡電腦的工廠。而僅僅是抽象一個工廠拿霉,用來生產(chǎn)聯(lián)想 Y 電腦吟秩、華碩 G 電腦、性能級顯卡绽淘、發(fā)燒級顯卡峰尝,然后組合就形成產(chǎn)品。

0x04 具體實(shí)現(xiàn)

抽象工廠時代
項(xiàng)目結(jié)構(gòu)圖
項(xiàng)目結(jié)構(gòu)圖.PNG
產(chǎn)品類

??為產(chǎn)品顯卡創(chuàng)建接口收恢。

// factory_pattern.abstract_factory.product.IGraphics
public interface IGraphics {
    void getGraphics(String series);
}

??為產(chǎn)品電腦創(chuàng)建接口武学。

// factory_pattern.abstract_factory.product.IComputer
public interface IComputer {
    void getComputer(String brand);
}

??拓展上述接口,采用需要組合的方式生產(chǎn)產(chǎn)品伦意,所以將類進(jìn)行細(xì)分拓展接口火窒。

??拓展顯卡接口 IGraphics ,定義性能級顯卡類 PerformanceGraphics 驮肉。

// factory_pattern.abstract_factory.product.impl.PerformanceGraphics
public class PerformanceGraphics implements IGraphics {
    @Override
    public void getGraphics(String series) {
        System.out.println("研發(fā)一個 " + series + " 顯卡");
    }
}

??拓展顯卡接口 IGraphics 熏矿,定義發(fā)燒級顯卡類 FeverGraphics

// factory_pattern.abstract_factory.product.impl.FeverGraphics
public class FeverGraphics implements IGraphics {
    @Override
    public void getGraphics(String series) {
        System.out.println("制造一個 " + series + " 顯卡");
    }
}

??拓展電腦接口 IComputer 离钝,定義聯(lián)想電腦類 LenovoComputer 票编。

// factory_pattern.abstract_factory.product.impl.LenovoComputer
public class LenovoComputer implements IComputer {
    @Override
    public void getComputer(String brand) {
        System.out.println("制造一臺 " + brand + " 筆記本電腦");
    }
}

??拓展電腦接口 IComputer ,定義華碩電腦類 AsusComputer 卵渴。

// factory_pattern.abstract_factory.product.impl.AsusComputer
public class AsusComputer implements IComputer {
    @Override
    public void getComputer(String brand) {
        System.out.println("研發(fā)一臺 " + brand + " 臺式電腦");
    }
}
工廠類

??為 Computer 和 Graphics 對象創(chuàng)建接口 IAbstractFactory 來獲取工廠慧域。

// factory_pattern.abstract_factory.factory.IAbstractFactory
public interface IAbstractFactory {
    IComputer createComputer(String brand);
    IGraphics createGraphics(String series);
}

??創(chuàng)建擴(kuò)展了 IAbstractFactory 的工廠接口,基于給定的信息生成實(shí)體類的對象浪读。

// factory_pattern.abstract_factory.factory.impl.GraphicsFactroy
public class GraphicsFactroy implements IAbstractFactory {
    @Override
    public IComputer createComputer(String brand) {
        return null;
    }
    @Override
    public IGraphics createGraphics(String series) {
        switch (series) {
            case "Performance" :
                return new PerformanceGraphics();
            case "Fever" :
                return new FeverGraphics();
            default :
                throw new IllegalArgumentException();
        }
    }
}
// factory_pattern.abstract_factory.factory.impl.ComputerFactory
public class ComputerFactory implements IAbstractFactory {
    @Override
    public IComputer createComputer(String brand) {
        switch (brand) {
            case "Lenovo" :
                return new LenovoComputer();
            case "Asus" :
                return new AsusComputer();
            default :
                throw new IllegalArgumentException();
        }
    }
    @Override
    public IGraphics createGraphics(String series) {
        return null;
    }
}

??創(chuàng)建一個工廠創(chuàng)造器 / 生成器類昔榴,通過傳遞品牌或型號來獲取工廠辛藻。

// factory_pattern.abstract_factory.factory.impl.FactoryProducer
public class FactoryProducer {
    public static IAbstractFactory getFactory(String choice){
        switch (choice) {
            case "Computer" :
                return new ComputerFactory();
            case "Graphics" :
                return new GraphicsFactroy();
            default :
                throw new IllegalArgumentException();
        }
    }
}
用戶類

??使用 FactoryProducer 來獲取 IAbstractFactory,通過傳遞類型信息來獲取實(shí)體類的對象互订。

// factory_pattern.abstract_factory.user.ComputerTest
public class ComputerTest {
    @Test
    public void testGetLenovoPerformanceComputer() {
        IAbstractFactory computerFactory = FactoryProducer.getFactory("Computer");
        IComputer lenPC = computerFactory.createComputer("Lenovo");
        IAbstractFactory graphicsFactory = FactoryProducer.getFactory("Graphics");
        IGraphics lenPer = graphicsFactory.createGraphics("Performance");
        lenPC.getComputer("Lenovo");
        lenPer.getGraphics("Performance");
    }
    @Test
    public void testGetAsusFeverComputer() {
        IAbstractFactory computerFactory = FactoryProducer.getFactory("Computer");
        IComputer lenPC = computerFactory.createComputer("Asus");
        IAbstractFactory graphicsFactory = FactoryProducer.getFactory("Graphics");
        IGraphics lenPer = graphicsFactory.createGraphics("Fever");
        lenPC.getComputer("Asus");
        lenPer.getGraphics("Fever");
    }
}
驗(yàn)證輸出

testGetLenovoPerformanceComputer

制造一臺 Lenovo 筆記本電腦
研發(fā)一個 Performance 顯卡

testGetAsusFeverComputer

研發(fā)一臺 Asus 臺式電腦
制造一個 Fever 顯卡

0x05 總結(jié)

??無論是簡單工廠吱肌,工廠方法模式,還是抽象工廠模式仰禽,他們都屬于工廠模式氮墨,在形式和特點(diǎn)上也是極為相似的,他們的最終目的都是為了解耦吐葵。在使用時勇边,我們不必去在意這個模式到底工廠方法模式還是抽象工廠模式,因?yàn)樗麄冎g的演變常常是令人琢磨不透的折联。經(jīng)常你會發(fā)現(xiàn)粒褒,明明使用的工廠方法模式,當(dāng)新需求來臨诚镰,稍加修改奕坟,加入了一個新方法后,由于類中的產(chǎn)品構(gòu)成了不同等級結(jié)構(gòu)中的產(chǎn)品族清笨,它就變成抽象工廠模式了月杉。而對于抽象工廠模式,當(dāng)減少一個方法使的提供的產(chǎn)品不再構(gòu)成產(chǎn)品族之后抠艾,它就演變成了工廠方法模式苛萎。

??所以,在使用工廠模式時检号,只需要關(guān)心降低耦合度的目的是否達(dá)到了腌歉。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市齐苛,隨后出現(xiàn)的幾起案子翘盖,更是在濱河造成了極大的恐慌,老刑警劉巖凹蜂,帶你破解...
    沈念sama閱讀 216,919評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件馍驯,死亡現(xiàn)場離奇詭異,居然都是意外死亡玛痊,警方通過查閱死者的電腦和手機(jī)汰瘫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,567評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擂煞,“玉大人混弥,你說我怎么就攤上這事【蹦龋” “怎么了剑逃?”我有些...
    開封第一講書人閱讀 163,316評論 0 353
  • 文/不壞的土叔 我叫張陵浙宜,是天一觀的道長官辽。 經(jīng)常有香客問我蛹磺,道長,這世上最難降的妖魔是什么同仆? 我笑而不...
    開封第一講書人閱讀 58,294評論 1 292
  • 正文 為了忘掉前任萤捆,我火速辦了婚禮,結(jié)果婚禮上俗批,老公的妹妹穿的比我還像新娘俗或。我一直安慰自己,他們只是感情好岁忘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,318評論 6 390
  • 文/花漫 我一把揭開白布辛慰。 她就那樣靜靜地躺著,像睡著了一般干像。 火紅的嫁衣襯著肌膚如雪帅腌。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,245評論 1 299
  • 那天麻汰,我揣著相機(jī)與錄音速客,去河邊找鬼。 笑死五鲫,一個胖子當(dāng)著我的面吹牛溺职,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播位喂,決...
    沈念sama閱讀 40,120評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼浪耘,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了塑崖?” 一聲冷哼從身側(cè)響起点待,我...
    開封第一講書人閱讀 38,964評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弃舒,沒想到半個月后癞埠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,376評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聋呢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,592評論 2 333
  • 正文 我和宋清朗相戀三年苗踪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片削锰。...
    茶點(diǎn)故事閱讀 39,764評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡通铲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出器贩,到底是詐尸還是另有隱情颅夺,我是刑警寧澤朋截,帶...
    沈念sama閱讀 35,460評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站吧黄,受9級特大地震影響部服,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拗慨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,070評論 3 327
  • 文/蒙蒙 一廓八、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧赵抢,春花似錦剧蹂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,697評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至其爵,卻和暖如春冒冬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背醋闭。 一陣腳步聲響...
    開封第一講書人閱讀 32,846評論 1 269
  • 我被黑心中介騙來泰國打工窄驹, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人证逻。 一個月前我還...
    沈念sama閱讀 47,819評論 2 370
  • 正文 我出身青樓乐埠,卻偏偏與公主長得像,于是被迫代替她去往敵國和親囚企。 傳聞我的和親對象是個殘疾皇子丈咐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,665評論 2 354

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