Carson帶你學設(shè)計模式:抽象工廠模式(Abstract Factory)


前言

  • 在上文提到的Carson帶你學設(shè)計模式:工廠方法模式(Factory Method),發(fā)現(xiàn)工廠方法模式存在一個嚴重的問題:一個具體工廠只能創(chuàng)建一類產(chǎn)品诉瓦;
  • 而在實際過程中,一個工廠往往需要生產(chǎn)多類產(chǎn)品允耿;
  • 為了解決上述的問題奕坟,我們又使用了一種新的設(shè)計模式:抽象工廠模式。

目錄

抽象工廠模式.jpg

1. 介紹

1.1 定義

抽象工廠模式罗侯,即Abstract Factory Pattern狐蜕,提供一個創(chuàng)建一系列相關(guān)或相互依賴對象的接口突倍,而無須指定它們具體的類蚂蕴;具體的工廠負責實現(xiàn)具體的產(chǎn)品實例苛萎。

抽象工廠模式與工廠方法模式最大的區(qū)別:抽象工廠中每個工廠可以創(chuàng)建多種類的產(chǎn)品;而工廠方法每個工廠只能創(chuàng)建一類

1.2 主要作用

允許使用抽象的接口來創(chuàng)建一組相關(guān)產(chǎn)品讲弄,而不需要知道或關(guān)心實際生產(chǎn)出的具體產(chǎn)品是什么措左,這樣就可以從具體產(chǎn)品中被解耦。

1.3 解決的問題

每個工廠只能創(chuàng)建一類產(chǎn)品

工廠方法模式的缺點


2. 模式原理

2.1 UML類圖

UML類圖

2.2 模式組成

組成(角色) 關(guān)系 作用
抽象產(chǎn)品族(AbstractProduct) 抽象產(chǎn)品的父類 描述抽象產(chǎn)品的公共接口
抽象產(chǎn)品(Product) 具體產(chǎn)品的父類 描述具體產(chǎn)品的公共接口
具體產(chǎn)品(Concrete Product) 抽象產(chǎn)品的子類避除;工廠類創(chuàng)建的目標類 描述生產(chǎn)的具體產(chǎn)品
抽象工廠(Creator) 具體工廠的父類 描述具體工廠的公共接口
具體工廠(Concrete Creator) 抽象工廠的子類媳荒;被外界調(diào)用 描述具體工廠;實現(xiàn)FactoryMethod工廠方法創(chuàng)建產(chǎn)品的實例

如何理解抽象產(chǎn)品族驹饺、抽象產(chǎn)品和具體產(chǎn)品的區(qū)別呢?請看下圖


概念區(qū)別.jpg

2.3 使用步驟

步驟1: 創(chuàng)建抽象工廠類缴渊,定義具體工廠的公共接口赏壹;
步驟2: 創(chuàng)建抽象產(chǎn)品族類 ,定義抽象產(chǎn)品的公共接口衔沼;
步驟3: 創(chuàng)建抽象產(chǎn)品類 (繼承抽象產(chǎn)品族類)蝌借,定義具體產(chǎn)品的公共接口;
步驟4: 創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類) & 定義生產(chǎn)的具體產(chǎn)品指蚁;
步驟5:創(chuàng)建具體工廠類(繼承抽象工廠類)菩佑,定義創(chuàng)建對應具體產(chǎn)品實例的方法;
步驟6:客戶端通過實例化具體的工廠類凝化,并調(diào)用其創(chuàng)建不同目標產(chǎn)品的方法創(chuàng)建不同具體產(chǎn)品類的實例


3. 實例講解

接下來我用一個實例來對抽象工廠模式進行更深一步的介紹稍坯。

3.1 實例概況

  • 背景:小成有兩間塑料加工廠(A廠僅生產(chǎn)容器類產(chǎn)品;B廠僅生產(chǎn)模具類產(chǎn)品);隨著客戶需求的變化瞧哟,A廠所在地的客戶需要也模具類產(chǎn)品混巧,B廠所在地的客戶也需要容器類產(chǎn)品;
  • 沖突:沒有資源(資金+租位)在當?shù)胤謩e開設(shè)多一家注塑分廠
  • 解決方案:在原有的兩家塑料廠里增設(shè)生產(chǎn)需求的功能勤揩,即A廠能生產(chǎn)容器+模具產(chǎn)品咧党;B廠間能生產(chǎn)模具+容器產(chǎn)品。

即抽象工廠模式

3.2 使用步驟

步驟1: 創(chuàng)建抽象工廠類陨亡,定義具體工廠的公共接口

abstract class Factory{
   public abstract Product ManufactureContainer();
    public abstract Product ManufactureMould();
}

步驟2: 創(chuàng)建抽象產(chǎn)品族類 傍衡,定義具體產(chǎn)品的公共接口;

abstract class AbstractProduct{
    public abstract void Show();
}

步驟3: 創(chuàng)建抽象產(chǎn)品類 负蠕,定義具體產(chǎn)品的公共接口蛙埂;

//容器產(chǎn)品抽象類
abstract class ContainerProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

//模具產(chǎn)品抽象類
abstract class MouldProduct extends AbstractProduct{
    @Override
    public abstract void Show();
}

步驟4: 創(chuàng)建具體產(chǎn)品類(繼承抽象產(chǎn)品類), 定義生產(chǎn)的具體產(chǎn)品虐急;

//容器產(chǎn)品A類
class ContainerProductA extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生產(chǎn)出了容器產(chǎn)品A");
    }
}

//容器產(chǎn)品B類
class ContainerProductB extends ContainerProduct{
    @Override
    public void Show() {
        System.out.println("生產(chǎn)出了容器產(chǎn)品B");
    }
}

//模具產(chǎn)品A類
class MouldProductA extends MouldProduct{

    @Override
    public void Show() {
        System.out.println("生產(chǎn)出了模具產(chǎn)品A");
    }
}

//模具產(chǎn)品B類
class MouldProductB extends MouldProduct{

    @Override
    public void Show() {
        System.out.println("生產(chǎn)出了模具產(chǎn)品B");
    }
}

步驟5:創(chuàng)建具體工廠類(繼承抽象工廠類)箱残,定義創(chuàng)建對應具體產(chǎn)品實例的方法;

//A廠 - 生產(chǎn)模具+容器產(chǎn)品
class FactoryA extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductA();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductA();
    }
}

//B廠 - 生產(chǎn)模具+容器產(chǎn)品
class FactoryB extends Factory{

    @Override
    public Product ManufactureContainer() {
        return new ContainerProductB();
    }

    @Override
    public Product ManufactureMould() {
        return new MouldProductB();
    }
}

步驟6:客戶端通過實例化具體的工廠類止吁,并調(diào)用其創(chuàng)建不同目標產(chǎn)品的方法創(chuàng)建不同具體產(chǎn)品類的實例

//生產(chǎn)工作流程
public class AbstractFactoryPattern {
    public static void main(String[] args){
        FactoryA mFactoryA = new FactoryA();
        FactoryB mFactoryB = new FactoryB();
        //A廠當?shù)乜蛻粜枰萜鳟a(chǎn)品A
        mFactoryA.ManufactureContainer().Show();
        //A廠當?shù)乜蛻粜枰>弋a(chǎn)品A
        mFactoryA.ManufactureMould().Show();

        //B廠當?shù)乜蛻粜枰萜鳟a(chǎn)品B
        mFactoryB.ManufactureContainer().Show();
        //B廠當?shù)乜蛻粜枰>弋a(chǎn)品B
        mFactoryB.ManufactureMould().Show();

    }
}

結(jié)果:

生產(chǎn)出了容器產(chǎn)品A
生產(chǎn)出了容器產(chǎn)品B
生產(chǎn)出了模具產(chǎn)品A
生產(chǎn)出了模具產(chǎn)品B

4. 優(yōu)點

  • 降低耦合
    抽象工廠模式將具體產(chǎn)品的創(chuàng)建延遲到具體工廠的子類中被辑,這樣將對象的創(chuàng)建封裝起來,可以減少客戶端與具體產(chǎn)品類之間的依賴敬惦,從而使系統(tǒng)耦合度低盼理,這樣更有利于后期的維護和擴展;

  • 更符合開-閉原則
    新增一種產(chǎn)品類時俄删,只需要增加相應的具體產(chǎn)品類和相應的工廠子類即可

簡單工廠模式需要修改工廠類的判斷邏輯

  • 符合單一職責原則
    每個具體工廠類只負責創(chuàng)建對應的產(chǎn)品

簡單工廠中的工廠類存在復雜的switch邏輯判斷

  • 不使用靜態(tài)工廠方法宏怔,可以形成基于繼承的等級結(jié)構(gòu)。

簡單工廠模式的工廠類使用靜態(tài)工廠方法


5. 缺點

抽象工廠模式很難支持新種類產(chǎn)品的變化畴椰。
這是因為抽象工廠接口中已經(jīng)確定了可以被創(chuàng)建的產(chǎn)品集合臊诊,如果需要添加新產(chǎn)品,此時就必須去修改抽象工廠的接口斜脂,這樣就涉及到抽象工廠類的以及所有子類的改變抓艳,這樣也就違背了“開發(fā)——封閉”原則。

對于新的產(chǎn)品族符合開-閉原則帚戳;對于新的產(chǎn)品種類不符合開-閉原則玷或,這一特性稱為開-閉原則的傾斜性。


6. 應用場景

在了解了優(yōu)缺點后片任,我總結(jié)了工廠方法模式的應用場景:

  • 一個系統(tǒng)不要求依賴產(chǎn)品類實例如何被創(chuàng)建偏友、組合和表達的表達,這點也是所有工廠模式應用的前提对供。
  • 這個系統(tǒng)有多個系列產(chǎn)品位他,而系統(tǒng)中只消費其中某一系列產(chǎn)品
  • 系統(tǒng)要求提供一個產(chǎn)品類的庫,所有產(chǎn)品以同樣的接口出現(xiàn),客戶端不需要依賴具體實現(xiàn)棱诱。

7. 總結(jié)

  • 本文主要對抽象工廠模式進行了全面介紹
  • 接下來我會對每種設(shè)計模式進行詳細的分析泼橘,歡迎關(guān)注Carson_Ho的簡書,不定期分享關(guān)于安卓開發(fā)的干貨迈勋,追求短炬灭、平、快靡菇,但卻不缺深度重归。

請點贊!因為你的鼓勵是我寫作的最大動力厦凤!

相關(guān)文章閱讀
這是一份全面 & 詳細的設(shè)計模式學習指南
Carson帶你學設(shè)計模式:單例模式(Singleton)
Carson帶你學設(shè)計模式:簡單工廠模式(SimpleFactoryPattern)
Carson帶你學設(shè)計模式:工廠方法模式(Factory Method)
Carson帶你學設(shè)計模式:抽象工廠模式(Abstract Factory)
Carson帶你學設(shè)計模式:策略模式(Strategy Pattern)
Carson帶你學設(shè)計模式:適配器模式(Adapter Pattern)
Carson帶你學設(shè)計模式:靜態(tài)代理模式(Proxy Pattern)
Carson帶你學設(shè)計模式:動態(tài)代理模式(Proxy Pattern)
Carson帶你學設(shè)計模式:模板方法模式(Template Method)
Carson帶你學設(shè)計模式:建造者模式(Builder Pattern)
Carson帶你學設(shè)計模式:外觀模式(Facade Pattern)
Carson帶你學設(shè)計模式:觀察者模式(Observer)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末鼻吮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子较鼓,更是在濱河造成了極大的恐慌椎木,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件博烂,死亡現(xiàn)場離奇詭異香椎,居然都是意外死亡,警方通過查閱死者的電腦和手機禽篱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進店門畜伐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人躺率,你說我怎么就攤上這事玛界。” “怎么了悼吱?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵慎框,是天一觀的道長。 經(jīng)常有香客問我后添,道長鲤脏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任吕朵,我火速辦了婚禮,結(jié)果婚禮上窥突,老公的妹妹穿的比我還像新娘努溃。我一直安慰自己,他們只是感情好阻问,可當我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布梧税。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪第队。 梳的紋絲不亂的頭發(fā)上哮塞,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天,我揣著相機與錄音凳谦,去河邊找鬼忆畅。 笑死,一個胖子當著我的面吹牛尸执,可吹牛的內(nèi)容都是我干的家凯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼如失,長吁一口氣:“原來是場噩夢啊……” “哼绊诲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起褪贵,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤掂之,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后脆丁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體世舰,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年偎快,在試婚紗的時候發(fā)現(xiàn)自己被綠了冯乘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡晒夹,死狀恐怖裆馒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情丐怯,我是刑警寧澤喷好,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站读跷,受9級特大地震影響梗搅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜效览,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一无切、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丐枉,春花似錦哆键、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽闪盔。三九已至,卻和暖如春辱士,著一層夾襖步出監(jiān)牢的瞬間泪掀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工颂碘, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留异赫,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓凭涂,卻偏偏與公主長得像祝辣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子切油,可洞房花燭夜當晚...
    茶點故事閱讀 45,077評論 2 355

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