抽象原廠模式

來源:互聯網
上載者:User

2018年8月24日17:20:30

抽象原廠模式定義

借我一隻晨光的鉛筆,明天就還給你。

現在我可以還你晨光的鉛筆了,你早已不在了,明天還是明天。

抽象原廠模式(Abstract Factory),提供一個建立一系列相關或相互依賴對象的介面,而無需指定它們具體的類。——《設計模式:可複用物件導向軟體的基礎》

使用情境

首先要來認識兩個新概念:產品族產品等級結構

產品族,是指不同產品等級結構中,功能相關的產品組成的家族。

產品等級結構, 即產品的繼承結構,繼承(或實現)同一抽象產品的具體產品屬於同一產品等級結構。

在後面的程式碼範例中,晨光文具和真彩文具是兩個產品族,繼承(或實現)鉛筆抽象產品的晨光鉛筆和真彩鉛筆是一個產品等級結構,繼承(或實現)橡皮抽象產品的晨光鉛筆和真彩鉛筆是另一個產品等級結構。【這個我用了繼承(或實現)是因為Java中有介面是實現的,抽象類別是繼承的,抽象產品既可以是介面,也可以是抽象類別,為了不誤導我自己,特意加上。】例子還有:Intel的主板、晶片集、CPU是一個產品族,AMD的主板、晶片集、CPU也是一個產品族,而這裡有三個產品等級結構,分別是:主板、晶片集、CPU。

想程式碼範例的時候,想我們經常用的東西,就想到了文具,想到了晨光和真彩。查了一下,沒想到小小文具,營業額超十億。

現在我們的目標是先賺他一個億,開一家部落格園文具(產品族),產品等級結構呢,他們都有,我們直接繼承(或實現)他們的抽象產品類就好了,多方便。這就是抽象原廠模式的好處。增加一個產品族,不用破壞原來代碼結構,符合開閉原則。

但是只有老產品,沒有什麼競爭力,要不我們增加一個新產品即新的產品等級結構,暫時就是碼農作弊專用智能筆,幫你輕鬆應對筆試,這時我們就要在部落格園文具(產品族)添加新成員,需要在部落格園文具具體工廠類中添加相關建立新產品的代碼,不符合開閉原則。這就是抽象原廠模式的缺點了。

綜上所述,結合其他情況,以下情況可以使用抽象原廠模式:

1、一個系統不應當依賴於產品執行個體如何被建立、組合和表達的細節,這對於所有類型的原廠模式都是重要的。

2、系統有多於一個的產品,且每次只使用其中一個產品族。

3、屬於同一產品族的產品將在一起使用,這一約束應該在系統設計中體現出來。

4、所有產品以自己繼承(或實現)的介面出現,從而用戶端不依賴於具體實現。

第1點,毋庸置疑。第2點和第3點,說的是我選擇晨光文具,我使用的就是晨光的鉛筆就要使用晨光的橡皮,要配套使用,不能是我使用了晨光的鉛筆卻使用真彩的橡皮。這個約束在這個例子看起來有點牽強,但是想一下這樣的情境:期末考試要同一文具,有兩種選擇,一種是晨光,一種是真彩,他們是配套的,晨光的鉛筆配晨光的橡皮,真彩的鉛筆配真彩的橡皮,這樣就舒服了。第4點,面向介面編程,降低耦合。

第2點和第3點,用上面提到的Intel、AMD產品族更貼切,Intel的CPU是無法和AMD的主板匹配的,AMD的CPU也無法和Intel的主板匹配,所以組裝電腦的時候,就預設有這個約束:只能使用同一個產品族中的產品。

關於抽象原廠模式的起源,是用於建立分屬於不同作業系統的視窗構建。比如:命令按鍵(Button)與文字框(Text)都是視窗構建,在UNIX作業系統的視窗環境和Windows作業系統的視窗環境中,這兩個構建有不同的本地實現,它們的細節有所不同。視窗構建時,只能選擇一個作業系統的Button和Text,如果不是,兩個作業系統都用不了,我要這視窗有何用?

角色

抽象工廠角色(Abstract Factory):具體工廠(產品族)公用介面

具體工廠角色(Concrete Factory):產品族

抽象產品角色(Abstract Product):產品等級結構

具體產品角色(Concrete Product):產品

圖示

程式碼範例

程式碼範例類依賴關係圖:

抽象工廠角色(AbstractFactory.java)

public interface AbstractFactory {    public Pencil createPencil();    public Eraser createEraser();}

具體工廠角色(ChenGuangFactory.java、TrueColorFactory.java)

// 晨光工廠public class ChenGuangFactory implements AbstractFactory {    @Override    public Pencil createPencil() {        return new ChenGuangPencil();    }    @Override    public Eraser createEraser() {        return new ChenGuangEraser();    }}// 真彩工廠public class TrueColorFactory implements AbstractFactory{    @Override    public Pencil createPencil() {        return new TrueColorPencil();    }    @Override    public Eraser createEraser() {        return new TrueColorEraser();    }}

抽象產品角色(Pencil.java、Eraser.java)

// 鉛筆public interface Pencil {    public void draw();}// 橡皮public interface Eraser {    public void erase();}

具體產品角色(ChenGuangPencil.java、TrueColorPencil.java、ChenGuangEraser.java、TrueColorEraser.java)

// 晨光鉛筆public class ChenGuangPencil implements Pencil {    @Override    public void draw() {        System.out.println("用晨光鉛筆畫圖。");    }}// 真彩鉛筆public class TrueColorPencil implements Pencil {    @Override    public void draw() {        System.out.println("用真彩鉛筆畫圖。");    }}// 晨光橡皮public class ChenGuangEraser implements Eraser {    @Override    public void erase() {        System.out.println("用晨光橡皮擦除晨光鉛筆畫的圖。");    }}// 真彩橡皮public class TrueColorEraser implements Eraser {    @Override    public void erase() {        System.out.println("用真彩橡皮擦除真彩鉛筆畫的圖。");    }}

測試類別(AbstractFactoryTest.java)

public class AbstractFactoryTest {    public static void main(String[] args) {        // 1、晨光        AbstractFactory factory = new ChenGuangFactory();        Pencil pencil = factory.createPencil();        pencil.draw(); // 用晨光鉛筆畫圖。        Eraser eraser = factory.createEraser();        eraser.erase(); // 用晨光橡皮擦除晨光鉛筆畫的圖。                // 2、真彩        AbstractFactory factoryT = new TrueColorFactory();        Pencil pencilT = factoryT.createPencil();        pencilT.draw(); // 用真彩鉛筆畫圖。        Eraser eraserT = factoryT.createEraser();        eraserT.erase(); // 用真彩橡皮擦除真彩鉛筆畫的圖。    }}

測試結果:

優點

1、擁有簡單原廠模式、Factory 方法模式一樣的優點:用戶端不需要知道對象被建立的細節

2、當產品族中多個對象被設計成一起工作時,它能保證用戶端始終只使用同一個產品族中的產品。

3、增加產品族,符合開閉原則。

缺點

1、增加產品等級結構時,不符合開閉原則。

總結

抽象原廠模式在Factory 方法模式的基礎上,增添了產品族產品等級結構的概念,以及只使用同一個產品族中的約束,使得抽象原廠模式符合現實生活中的某些情境,成為實用的設計模式,再加上抽象原廠模式實現高內聚低耦合,也為其廣泛應用提供基礎。

(給晨光和真彩做廣告,是不是應該收點廣告費???)

參考:

《JAVA與模式》之抽象原廠模式

2018年8月25日18:31:58

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.