最近中文字幕高清中文字幕无,亚洲欧美高清一区二区三区,一本色道无码道dvd在线观看 ,一个人看的www免费高清中文字幕

抽象工廠模式

抽象工廠模式用來解決產(chǎn)品族的實例化問題。比如說現(xiàn)在有個家居設計軟件,通過軟件模擬房間,擺放各種虛擬的家具,看效果如何。我們可以放入電視柜、茶幾、餐桌、床等等。這一系列的家具就叫做產(chǎn)品族。產(chǎn)品族面臨的問題是,當一個產(chǎn)品族切換到另外一個產(chǎn)品族時,如何讓代碼的修改最小。也就是說如何做到開閉原則。

想把設計好的方案從簡約現(xiàn)代切換到歐式風格家具,怎么才能做到修改最?。咳绻捎煤唵喂S,那么每種產(chǎn)品都對應一個工廠,工廠負責產(chǎn)出不同風格的產(chǎn)品。設計方案中用到 n 種產(chǎn)品就要修改 n 處代碼。這顯然不是最佳的方法。此時,我們需要抽象工廠模式來解決這個問題。抽象工廠模式中,每個工廠的實現(xiàn)負責生產(chǎn)自己產(chǎn)品族的產(chǎn)品。示意圖如下:
圖片描述

1. 實現(xiàn)抽象工廠

為了便于理解和展示,我們假設只有兩種家具----椅子和桌子。

首先定義每種家具的接口,只有一個方法用來獲取家具說明。

椅子:

public interface Chair {
    void getChairIntroduction();
}

桌子:

public interface Desk {
    void getDeskIntroduction();
}

以椅子為例,我們分別實現(xiàn)簡約現(xiàn)代和歐式兩種風格。
簡約現(xiàn)代風格椅子:

public class ModernStyleChair implements Chair {
    @Override
    public void getChairIntroduction() {
        System.out.println("這是一個現(xiàn)代簡約風格的椅子");
    }
}

歐式風格椅子:

public class EuropeanStyleChair implements Chair {
    @Override
    public void getChairIntroduction() {
        System.out.println("這是一個歐式風格的椅子");
    }
}

桌子也有兩種實現(xiàn),代碼這里省略。

產(chǎn)品我們已經(jīng)編寫完成。接下來我們來看看工廠的代碼。

首先我們定義一個家具工廠接口,可以生產(chǎn)椅子和桌子:

public interface FurnitureFactory {
    Chair createChair();
    Desk createDesk();
}

由于我們支持兩種不同的風格,所以我們編寫兩個實現(xiàn)類。

簡約風格家具工廠:

public class ModernFurnitureFactory implements FurnitureFactory{
    @Override
    public Chair createChair() {
        return new ModernStyleChair();
    }

    @Override
    public Desk createDesk() {
        return new ModernStyleDesk();
    }
}

歐式風格家具工廠:

public class EuropeanFurnitureFactory implements FurnitureFactory{
    @Override
    public Chair createChair() {
        return new EuropeanStyleChair();
    }

    @Override
    public Desk createDesk() {
        return new EuropeanStyleDesk();
    }
}

上面的代碼中,每種工廠各自實現(xiàn)如何生產(chǎn)兩種不同的家具。

客戶端代碼如下:

public class Client {
    public static void main(String[] args) {
        FurnitureFactory furnitureFactory = new EuropeanFurnitureFactory();
        Chair chair = furnitureFactory.createChair();
        Desk desk = furnitureFactory.createDesk();

        chair.getChairIntroduction();
        desk.getDeskIntroduction();
    }
}

客戶端代碼中,我們實例化的是歐式家具工廠,那么所生產(chǎn)的椅子和桌子應該是歐式風格。執(zhí)行后輸出如下:

這是一個歐式風格的椅子
這是一個歐式風格的桌子

和我們的預期相符。如果想要更換產(chǎn)品族,從現(xiàn)代簡約切換到歐式,我們只需要修改一處代碼。

FurnitureFactory furnitureFactory = new ModernFurnitureFactory();

僅通過更換抽象工廠的實現(xiàn)即可實現(xiàn)。修改后執(zhí)行結果如下:

這是一個現(xiàn)代簡約風格的椅子
這是一個現(xiàn)代簡約風格的桌子

可以看到已經(jīng)切換到簡約風格的產(chǎn)品族。這個過程中并不需要改任何產(chǎn)品使用的代碼。

如果增加別的風格產(chǎn)品族,只需要新建新風格的產(chǎn)品族產(chǎn)品,增加新風格產(chǎn)品族的工廠實現(xiàn)即可。
類圖:
圖片描述

2. 抽象工廠優(yōu)缺點

2.1 優(yōu)點

  1. 分離了產(chǎn)品類和客戶端類:客戶端只依賴抽象的產(chǎn)品接口。此外,如何生產(chǎn)產(chǎn)品被封裝在工廠內部;
  2. 方便切換產(chǎn)品族:客戶端代碼只需要初始化一次工廠實現(xiàn)。這意味著在切換產(chǎn)品族的時候,只需要修改一行代碼,換一個工廠實現(xiàn)即可;
  3. 保證產(chǎn)品的一致性:使用抽象工廠,可以保證你從相同工廠生產(chǎn)的產(chǎn)品都屬于同一個產(chǎn)品族。不會出現(xiàn)椅子是現(xiàn)代簡約風格,而桌子是歐式風格的情況。

2.2 缺點

添加新的產(chǎn)品時,改動較多。例子從兩個維度定義產(chǎn)品,一是不同產(chǎn)品,比如桌子、椅子。另外是不同族,例如現(xiàn)代簡約和歐式。使用抽象工廠,優(yōu)化了產(chǎn)品族,也就是第二個維度變化的難度。但是當添加新的產(chǎn)品時改動就會比較多。比如我們要添加一個新的產(chǎn)品是電視柜。那么需要修改抽象工廠,添加生產(chǎn)電視柜的方法。此外,有幾種工廠的實現(xiàn),我們就需要修改幾個類,添加具體的生產(chǎn)實現(xiàn)。

3. 抽象工廠適用場景

  1. 你的系統(tǒng)中,需要使用不同產(chǎn)品族中的某一個產(chǎn)品族來操作。 比如說DB源。如果想切換DB,只需要切換DB源即可,其他代碼基本上不需要改動;
  2. 你的系統(tǒng)中,需要保證某些產(chǎn)品的一致性。 比如操作系統(tǒng)的外觀,當切換到夜間模式時,所有的組件都會換為夜間模式風格。

4. 小結

抽象工廠可以做到一組產(chǎn)品的使用和生產(chǎn)相分離。通過抽象工廠模式,我們切換一組產(chǎn)品族的,只需要更換抽象工廠實現(xiàn)即可。由于產(chǎn)品生產(chǎn)被分離出去,所以添加新的產(chǎn)品族完全通過擴展來實現(xiàn)的。很好的實現(xiàn)了開閉原則。如果你要生產(chǎn)的產(chǎn)品很多,而且是一個產(chǎn)品族。并且面臨不同產(chǎn)品族切換的情況。那么可以考慮通過抽象工廠來實現(xiàn)。