設(shè)計(jì)模式:抽象工廠模式,結(jié)合類圖秒懂!

通過(guò)前篇文章《設(shè)計(jì)模式:工廠模式,解除耦合的利器》的介紹,我們對(duì)工廠模式有了深入的了解,今天繼續(xù)介紹一種特殊的工廠模式,也就是抽象工廠模式。

定義

抽象工廠模式:提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無(wú)須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬于對(duì)象創(chuàng)建型模式,是工廠方法模式的升級(jí)版,在有多個(gè)業(yè)務(wù)品種、業(yè)務(wù)分類時(shí),通過(guò)抽象工廠模式產(chǎn)生需要的對(duì)象是一種非常好的解決方式。

抽象工廠模式包含了幾個(gè)角色:

AbstractFactory:用于聲明生成抽象產(chǎn)品的方法

ConcreteFactory:實(shí)現(xiàn)了抽象工廠聲明的生成抽象產(chǎn)品的方法,生成一組具體產(chǎn)品,這些產(chǎn)品構(gòu)成了一個(gè)產(chǎn)品族,每一個(gè)產(chǎn)品都位于某個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)中;

AbstractProduct:為每種產(chǎn)品聲明接口,在抽象產(chǎn)品中定義了產(chǎn)品的抽象業(yè)務(wù)方法;

Product:定義具體工廠生產(chǎn)的具體產(chǎn)品對(duì)象,實(shí)現(xiàn)抽象產(chǎn)品接口中定義的業(yè)務(wù)方法。

這是它的通用類圖:

抽象工廠通用源碼類圖.png

其中 AbstractProductA 和 AbstractProductB 就是兩個(gè)產(chǎn)品族的抽象類 (或者接口),而 Product1 和 Product2 就是產(chǎn)品族下的具體產(chǎn)品類,AbstractCreator 就是工廠的抽象。

我們可以用操作系統(tǒng)來(lái)舉例,現(xiàn)在市面上用的最多的兩種PC端操作系統(tǒng)是windows和Linux,兩個(gè)系統(tǒng)都有共同類型的組件,如文件夾,按鈕,文本等。套用下抽象工廠的通用類圖,我們不難發(fā)現(xiàn),兩個(gè)系統(tǒng)就相當(dāng)于產(chǎn)品組抽象類AbstractProductA 和 AbstractProductB,而按鈕、文本這些組件就是具體的產(chǎn)品類。

然后再來(lái)分析一下,如果有一個(gè)應(yīng)用要在兩個(gè)系統(tǒng)上運(yùn)行,應(yīng)該怎么設(shè)計(jì)?是編寫(xiě)兩套程序運(yùn)行于不同的系統(tǒng)上?這樣實(shí)在是太浪費(fèi)資源了,我們可以通過(guò)抽象工廠模式屏蔽掉操作系統(tǒng)對(duì)應(yīng)用的影響。軟件功能、邏輯、UI 都一個(gè)非常類似,唯一的不同是調(diào)用不同的工廠方法,由不同的產(chǎn)品類去處理與操作系統(tǒng)交互的信息,而這就是抽象工廠的優(yōu)勢(shì)。

代碼編寫(xiě)

抽象工廠的通用類圖我們已經(jīng)了解了,下面就是具體代碼的實(shí)現(xiàn):

產(chǎn)品族的抽象類,AbstractProductAAbstractProductB,

public abstract class AbstractProductA {
    //每個(gè)產(chǎn)品共有的方法
    public void shareMethod() {
    }

    // 每個(gè)產(chǎn)品相同方法,不同實(shí)現(xiàn)
    public abstract void doSomething();
}
public abstract class AbstractProductB {
    //每個(gè)產(chǎn)品共有的方法
    public void shareMethod() {
    }

    // 每個(gè)產(chǎn)品相同方法,不同實(shí)現(xiàn)
    public abstract void doSomething();
}

兩個(gè)產(chǎn)品族的具體實(shí)現(xiàn)類代碼,

public class ProductA1 extends AbstractProductA {
    public void doSomething() {
        System.out.println("我是產(chǎn)品A1");
    }
}
public class ProductA2 extends AbstractProductA {
    public void doSomething() {
        System.out.println("我是產(chǎn)品A2");
    }
}
public class ProductB1 extends AbstractProductB {
    public void doSomething() {
        System.out.println("我是產(chǎn)品B1");
    }
}
public class ProductB2 extends AbstractProductB {
    public void doSomething() {
        System.out.println("我是產(chǎn)品B2");
    }
}

抽象工廠類AbstractCreator,有N個(gè)產(chǎn)品族,在抽象工廠類中就應(yīng)該有N個(gè)創(chuàng)建方法。我們這里定義兩個(gè)產(chǎn)品族的產(chǎn)品創(chuàng)建,代碼如下:

public abstract class AbstractCreator {
    //創(chuàng)建A產(chǎn)品
    public abstract AbstractProductA createProductA();

    //創(chuàng)建B產(chǎn)品
    public abstract AbstractProductB createProductB();
}

然后是創(chuàng)建產(chǎn)品的具體工廠,有N個(gè)產(chǎn)品等級(jí)就應(yīng)該有N個(gè)實(shí)現(xiàn)工廠類,在每個(gè)實(shí)現(xiàn)工廠中,實(shí)現(xiàn)不同產(chǎn)品族的生產(chǎn)任務(wù)。

public class Creator1 extends AbstractCreator {
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}
public class Creator2 extends AbstractCreator {
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}

到此為止,我們把所有的角色都創(chuàng)建出來(lái)了,最后設(shè)計(jì)一個(gè)場(chǎng)景類,驗(yàn)證下是否能輸出對(duì)應(yīng)產(chǎn)品的信息,

public class Client {
    public static void main(String[] args) {
        //定義出兩個(gè)工廠
        AbstractCreator creator1 = new Creator1();
        AbstractCreator creator2 = new Creator2();
        //產(chǎn)生A1對(duì)象
        AbstractProductA a1 = creator1.createProductA();
        //產(chǎn)生A2對(duì)象
        AbstractProductA a2 = creator2.createProductA();
        //產(chǎn)生B1對(duì)象
        AbstractProductB b1 = creator1.createProductB();
        //產(chǎn)生B2對(duì)象
        AbstractProductB b2 = creator2.createProductB();
        a1.doSomething();
        a2.doSomething();
        b1.doSomething();
        b2.doSomething();
    }
}

運(yùn)行的結(jié)果為:

我是產(chǎn)品A1
我是產(chǎn)品A2
我是產(chǎn)品B1
我是產(chǎn)品B2

總結(jié)

總結(jié)下抽象工廠模式的特點(diǎn),抽象工廠是所有形式的工廠模式中最為抽象和最具一般性的一種形態(tài),其優(yōu)缺點(diǎn)大致如下:

1、隔離了具體類的生成,使得客戶并不需要知道什么被創(chuàng)建,具有良好的封裝性。

2、橫向擴(kuò)展容易。同個(gè)產(chǎn)品族如果需要增加多個(gè) 產(chǎn)品,只需要增加新的工廠類和產(chǎn)品類即可。

3、縱向擴(kuò)展困難。如果增加新的產(chǎn)品組,抽象工廠類也要添加創(chuàng)建該產(chǎn)品組的對(duì)應(yīng)方法,這樣一來(lái)所有的具體工廠類都要做修改了,嚴(yán)重違背了開(kāi)閉原則。

參考:
《設(shè)計(jì)模式之禪》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 工廠方法模式通過(guò)引入工廠等級(jí)結(jié)構(gòu),解決了簡(jiǎn)單工廠模式中工廠類職責(zé)太重的問(wèn)題,但由于工廠方法模式中的每個(gè)工廠只生產(chǎn)一...
    justCode_閱讀 1,298評(píng)論 1 6
  • 設(shè)計(jì)原則: 要依賴抽象,不要依賴具體類 目錄 本文的結(jié)構(gòu)如下: 什么是抽象工廠模式 為什么要用該模式 模式的結(jié)構(gòu) ...
    w1992wishes閱讀 1,239評(píng)論 0 6
  • 工廠模式是我們最常用的實(shí)例化對(duì)象模式了,是用工廠方法代替new操作的一種模式。通常我們所說(shuō)的工廠模式是指工廠方法模...
    zfylin閱讀 1,405評(píng)論 0 7
  • 職場(chǎng)中的六要素: 一個(gè)職場(chǎng)新人,如果能做到以下幾點(diǎn),不愁日后沒(méi)有加薪晉職的機(jī)會(huì)。 ① 認(rèn)清自己的位置 ② 放低自己...
    靜月荷閱讀 658評(píng)論 1 5
  • 話說(shuō)自從寶玉認(rèn)識(shí)了秦鐘以后,從不愛(ài)讀書(shū)一下變得勤奮起來(lái),自己鬧著要上學(xué)。這一家老小可不喜歡,特別是襲人,從頭一天晚...
    楊丹曦閱讀 1,715評(píng)論 0 2

友情鏈接更多精彩內(nèi)容