設計模式學習筆記(六):抽象工廠模式

1 相關術語

在瞭解抽象工廠模式以前,首先來了解一下兩個術語:java

  • 產品等級結構
  • 產品族

1.1 產品等級結構

產品等級結構也就是產品的繼承結構,例如一個抽象類是電視機,子類有不一樣品牌的電視機,好比海爾電視機,海信電視機,TCL電視機,而抽象電視機與具體品牌的電視機之間構成了一個產品等級結構,抽象電視機是父類,而具體品牌的電視機是子類。測試

1.2 產品族

產品族是指由一個同一個工廠產生的位於不一樣產品等級結構中的一組產品,例如海爾電器工廠生產的海爾電視機,海爾電冰箱。海爾電視機位於電視機產品等級結構中,海爾電冰箱位於電冰箱產品等級結構中,海爾電視機與海爾電冰箱共同構成了一個產品族。spa

二者示意圖以下:設計

在這裏插入圖片描述

2 抽象工廠模式

**抽象工廠模式:提供一個建立一系列相關或相互依賴對象的接口,而無須指定它們具體的類。
抽象工廠模式又叫Kit模式,是一種對象建立型模式。**code

結構圖以下:
在這裏插入圖片描述對象

抽象工廠模式包含四個角色:blog

  • AbstractFactory(抽象工廠):聲明瞭一組用於建立一族產品的方法,每個方法對應一種產品
  • ConcreteFactory(具體工廠):實現了在抽象工廠中聲明的建立產品的方法,生成一組具體產品,這些產品構成了一個產品族,每個產品都位於某個產品的等級結構中
  • AbstractProduct(抽象產品):爲每種產品聲明接口,在抽象產品中聲明瞭產品所具備的業務方法
  • ConcreteProduct(具體產品):定義具體工廠生產的具體對象,實如今抽象層產品接口中聲明的業務方法

3 實例

界面皮膚庫設計:開發一套皮膚庫,用戶能夠經過菜單選擇皮膚,不一樣的皮膚提供視覺不一樣的按鈕,文本框等UI元素。

這裏簡單起見假設開發兩套皮膚:繼承

  • 春季皮膚(SpringSkin)
  • 夏季皮膚(SummerSkin)

每套皮膚具備如下UI元素:接口

  • 按鈕(Button)
  • 文本框(TextField)
  • 組合框(ComboBox)

首先是UI元素,包括抽象元素以及具體元素:圖片

interface Button
{
    void display();
}

class SpringButton implements Button
{
    public void display()
    {
        System.out.println("春季皮膚按鈕");
    }
}

class SummerButton implements Button
{
    public void display()
    {
        System.out.println("夏季皮膚按鈕");
    }
}

interface TextField
{
    void display();
}

class SpringTextField implements TextField
{
    public void display()
    {
        System.out.println("春季皮膚文本框");
    }
}

class SummerTextField implements TextField
{
    public void display()
    {
        System.out.println("夏季皮膚文本框");
    }
}

interface ComboBox
{
    void display();
}

class SpringComboBox implements ComboBox
{
    public void display()
    {
        System.out.println("春季皮膚組合框");
    }
}

class SummerComboBox implements ComboBox
{
    public void display()
    {
        System.out.println("夏季皮膚組合框");
    }
}

接着是工廠類,包括抽象工廠以及具體工廠:

interface SkinFactory
{
    Button createButton();
    TextField createTextField();
    ComboBox createComboBox();
}

class SpringSkinFactory implements SkinFactory
{
    public Button createButton()
    {
        return new SpringButton();
    }

    public TextField createTextField()
    {
        return new SpringTextField();
    }

    public ComboBox createComboBox()
    {
        return new SpringComboBox();
    }
}

class SummerSkinFactory implements SkinFactory
{
    public Button createButton()
    {
        return new SummerButton();
    }

    public TextField createTextField()
    {
        return new SummerTextField();
    }

    public ComboBox createComboBox()
    {
        return new SummerComboBox();
    }
}

測試:

public class Test
{
    public static void main(String[] args) {
        SkinFactory factory = new SpringSkinFactory();
        factory.createButton().display();
        factory.createTextField().display();
        factory.createComboBox().display();
        
        factory = new SummerSkinFactory();
        factory.createButton().display();
        factory.createTextField().display();
        factory.createComboBox().display();
    }
}

4 有關OCP

雖然使用抽象工廠模式增長新的皮膚界面很是方便,可是若是增長一個UI元素,會修改大量的代碼,須要修改抽象工廠以及每個具體工廠類,也就是說,不可以在符合OCP(開放閉合原則)的前提下增長新的組件。
這是抽象工廠模式的最大缺點,儘管增長新的產品族(這裏是皮膚)很是方便,可是增長新的產品等級結構(這裏是UI元素)很麻煩。抽象工廠模式的這種性質叫作開閉原則的傾斜性。所以設計人員在設計之初須要全面考慮,不然新增產品結構會致使大量的代碼修改。

5 主要優勢

  • 隔離:抽象工廠模式隔離了具體類的生成,使得客戶並不須要知道什麼被建立。因爲這種隔離更換一個具體工廠類變得很相對容易,全部的具體工廠都實現了在抽象工廠中聲明的那些公共接口,所以只需改變具體工廠的實例,就能夠在某種程度上改變整個軟件系統的行爲
  • 同一產品族對象:當一個產品族中的多個對象被設計成一塊兒工做時,它可以保證客戶端始終只使用同一個產品族中的對象
  • 增長產品族容易:增長新的產品族容易,無須修改已有系統,符合OCP

6 主要缺點

主要缺點是增長新的產品等級結構麻煩,須要對系統進行大量的修改,違背了OCP

7 適用場景

  • 一個系統不當應依賴與產品類實例如何被建立,組合和表達細節,這對於全部類型的工廠模式都是很重要的,用戶無須關心對象的建立過程,將對象的建立以及使用解耦
  • 系統中有多於一個的產品族,而每次只使用其中某一產品族
  • 屬於同一個產品族的產品將在一塊兒使用,這一約束必須在系統的設計中體現出來。同一個產品族中的產品能夠是沒有任何關係的對象,可是它們都具備一些共同的約束。例如同一皮膚下的按鈕以及文本框,按鈕與文本框沒有直接聯繫,可是都屬於同一皮膚
  • 產品等級結構穩定,設計完成後,不會向系統中增長新的產品等級結構或者刪除已有的產品等級結構

8 總結

相關文章
相關標籤/搜索