設計模式 —— 抽象工廠模式

鐵鏽的秀發表於2019-02-27

簡介

在瞭解抽象工廠模式之前,我們必須先了解一個概念產品族。所謂的產品族:是指位於不同產品等級結構中,功能相關聯的產品組成的家族。

舉個例子:在肥宅心中除了快樂水最喜歡的就是動漫了。

產品族
在上面的圖中,熱血番和搞笑番稱為兩個不同的等級結構;而國產動漫和日本動漫則稱為兩個不同的產品族。具體點就是。國漫的熱血番和日漫的熱血番屬於同一等級結構,國漫的搞笑番和日漫的搞笑番屬於同一等級結構;國漫熱血番和國漫搞笑番屬於同一產品族,日漫熱血番和日漫搞笑番屬於同一產品族。

明白了等級結構和產品族的概念,我們來看抽象工廠的定義:抽象工廠模式(Abstract Factory Pattern)是為建立一組相關或相互依賴的物件提供一個介面,而且無需指定他們的具體類。

例項

就以動漫為例子:

產品介面定義:

// 熱血番劇
public interface BloodDrama {
    String name();
}
// 搞笑番劇
public interface FunnyDrama {
    String name();
}
複製程式碼

產品具體實現:

// 中國熱血番
public class ChinaBloodDrama implements BloodDrama {
    @Override
    public String name() {
        return "中國熱血番";
    }
}
// 中國搞笑番
public class ChinaFunnyDrama implements FunnyDrama {
    @Override
    public String name() {
        return "中國搞笑番";
    }
}
//日本熱血番
public class JapanBloodDrama implements BloodDrama {
    @Override
    public String name() {
        return "日本熱血番";
    }
}
//日本搞笑番
public class JapanFunnyDrama implements FunnyDrama {
    @Override
    public String name() {
        return "日本搞笑番";
    }
}
複製程式碼

工廠介面定義:

public interface Factory {
    BloodDrama createBloodDrama();
    FunnyDrama createFunnyDrama();
}
複製程式碼

工廠具體實現:

// 國漫工廠
public class ChinaAnimeFactory implements Factory {
    @Override
    public BloodDrama createBloodDrama() {
        return new ChinaBloodDrama();
    }

    @Override
    public FunnyDrama createFunnyDrama() {
        return new ChinaFunnyDrama();
    }
}

// 日漫工廠
public class JapanAnimeFactory implements Factory {
    @Override
    public BloodDrama createBloodDrama() {
        return new JapanBloodDrama();
    }

    @Override
    public FunnyDrama createFunnyDrama() {
        return new JapanFunnyDrama();
    }
}
複製程式碼

客戶端(肥宅):

public class Fz {
    @Test
    public void watch() {
        // 國漫工廠
        Factory chinaAnimeFactory = new ChinaAnimeFactory();
        System.out.println("肥宅觀看:" + chinaAnimeFactory.createBloodDrama().name());
        System.out.println("肥宅觀看:" + chinaAnimeFactory.createFunnyDrama().name());

        // 日漫工廠
        Factory japanAnimeFactory = new JapanAnimeFactory();
        System.out.println("肥宅觀看:" + japanAnimeFactory.createBloodDrama().name());
        System.out.println("肥宅觀看:" + japanAnimeFactory.createFunnyDrama().name());
    }
}
複製程式碼

類圖

抽象工廠

優點

  1. 具有工廠方法模式的優點外;

  2. 在類內部對產品族的關聯關係進行定義和描述,而不必專門引入一個新的類來進行管理;

  3. 當一個產品族中的多個物件被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的物件。

缺點

產品族 的擴充套件將是一件十分費力的事情,假如產品族中需要增加一個新的產品,則幾乎所有的工廠類都需要進行修改。例如上面例子擴充套件一個 治癒番。所以使用抽象工廠模式時,對產品等級結構的劃分是非常重要的。

適用場景

當需要建立的物件是一系列相互關聯或相互依賴的產品族時,便可以使用抽象工廠模式。例如 系統日誌記錄:可能儲存到資料庫、本地檔案、快取、遠端伺服器等,使用者可以自己選擇記錄方式。

總結

無論是簡單工廠模式,工廠方法模式,還是抽象工廠模式,他們都屬於工廠模式,在形式和特點上也是極為相似的,他們的最終目的都是為了解耦。在使用時,我們不必去在意這個模式到底工廠方法模式還是抽象工廠模式,因為他們之間的演變常常是令人琢磨不透的。經常你會發現,明明使用的工廠方法模式,當新需求來臨,稍加修改,加入了一個新方法後,由於類中的產品構成了不同等級結構中的產品族,它就變成抽象工廠模式了;而對於抽象工廠模式,當減少一個方法使的提供的產品不再構成產品族之後,它就演變成了工廠方法模式。所以,在使用工廠模式時,只需要關心降低耦合度的目的是否達到了。

相關文章