設計模式之抽象工廠

抽象工廠模式銅工廠方法模式同樣,也是有抽象工廠、具體工廠、抽象產品、具體產品4個要素構成,可是抽象工廠中方法個數不一樣,抽象產品的個數也不一樣。那麼這篇文章主要介紹一下抽象工廠。編程

說到抽象工廠不知道有沒有些許的迷茫,筆者在剛剛接觸的時候倒是很迷茫的,其中最難理解的可能就是抽象。什麼是抽象?函數

抽象:抽象是從衆多的事物中抽取出共同的、本質性的特徵,而捨棄其非本質的特徵的過程。具體地說,抽象就是人們在實踐的基礎上,對於豐富的感性材料經過去粗取精、去僞存真、由此及彼、由表及裏的加工製做,造成概念、判斷、推理等思惟形式,以反映事物的本質和規律的方法。 ——節選自百度百科spa

筆者的理解的抽象則是抽離實物的本質,去掉其中不中要的部分。但願你們也能對抽象有一個簡單的理解,既然理解了抽象,那麼抽象工廠模式天然也是如此,文章中開頭說到抽象工廠模式銅工廠方法模式同樣,其實也不大相同,其實抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級的產品,而抽象工廠模式可生產多個等級的產品。code

什麼是抽象工廠模式

抽象工廠模式:是一種爲訪問類提供一個建立一組相關或相互依賴對象的接口,且訪問類無須指定所要產品的具體類就能獲得同族的不一樣等級的產品的模式結構。然而筆者理解的抽象工廠是這樣的,爲建立一組相關或依賴的對象提供一個接口,並且無需指定他們的具體類。對象

使用抽象工廠模式通常要知足如下條件。blog

  1. 系統中有多個產品族,每一個具體工廠建立同一族但屬於不一樣等級結構的產品。
  2. 系統一次只可能消費其中某一族產品,即同族的產品一塊兒使用。

抽象工廠定義了用於建立不一樣產品的接口,但將實際的建立工做留給了具體工廠類。每一個工廠類型都對應一個特定的產品變體。在建立產品時,客戶端代碼調用的是工廠對象的構建方法,而不是直接調用構造函數(new操做符)。因爲一個工廠對應一種產品變體,所以它建立的全部產品均可相互兼容。客戶端代碼僅經過其抽象接口與工廠和產品進行交互。該接口容許同一客戶端代碼與不一樣產品進行交互。 你只需建立一個具體工廠類並將其傳遞給客戶端代碼便可。接口

抽象工廠模式優缺點

抽象工廠更像一個複雜版本的策略模式,策略模式經過更換策略來改變處理方式或者結果;而抽象工廠的客戶端,經過更改工廠還改變結果。因此在使用的時候,就使用客戶端和更換工廠,而看不到產品自己。產品

工廠方法目的是生產產品,因此能看到產品,並且還要使用產品。固然,若是產品在建立者內部使用,那麼工廠方法就是爲了完善建立者,從而可使用建立者。另外建立者自己是不能更換所生產產品的。it

優勢
  1. 能夠在類的內部對產品族中相關聯的多等級產品共同管理,而沒必要專門引入多個新的類來進行管理
  2. 當須要產品族時,抽象工廠能夠保證客戶端始終只使用同一個產品的產品組
  3. 增長新的產品更加容易,抽象工廠加強了程序的可擴展性,當增長一個新的產品族時,不須要修改原代碼
缺點
  1. 當產品族中須要增長一個新的產品時,全部的工廠類都須要進行修改
  2. 增長了系統的抽象性和理解難度

示例

抽象工廠模式的主要角色以下:class

  1. 抽象工廠:提供了建立產品的接口,它包含多個建立產品的方法newProduct(),能夠建立多個不一樣等級的產品。
  2. 具體工廠:主要是實現抽象工廠中的多個抽象方法,完成具體產品的建立。
  3. 抽象產品:定義了產品的規範,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。
  4. 具體產品:實現了抽象產品角色所定義的接口,由具體工廠來建立,它同具體工廠之間是多對一的關係。

類圖以下所示:

image

代碼示例:

// 抽象產品A接口
interface AbstractProductA {}
// 抽象產品B接口
interface AbstractProductB {}

// 抽象工廠接口
interface AbstractFactory {
    createProductA() : AbstractProductA;
    createProductB() : AbstractProductB;
}

// 具體工廠1
class ConcreteFactory1 implements AbstractFactory {
    constructor() {}
    public createProductA() : AbstractProductA {
        return new ConcreteProductA1();
    }
    public createProductB() : AbstractProductB {
        return new ConcreteProductB1();
    }
}

// 具體工廠2
class ConcreteFactory2 implements AbstractFactory {
    constructor() {}
    public createProductA() : AbstractProductA {
        return new ConcreteProductA2();
    }
    public createProductB() : AbstractProductB {
        return new ConcreteProductB2();
    }
}

// 具體產品A1
class ConcreteProductA1 implements AbstractProductA {}
// 具體產品A2
class ConcreteProductA2 implements AbstractProductA {}
// 具體產品B1
class ConcreteProductB1 implements AbstractProductB {}
// 具體產品B2
class ConcreteProductB2 implements AbstractProductA {}

// 使用
const factory1 : AbstractFactory = new ConcreteFactory1();
const factory2 : AbstractFactory = new ConcreteFactory2();
const productA1 : AbstractProductA = factory1.createProductA();
const productA2 : AbstractProductA = factory2.createProductA();
const productB1 : AbstractProductB = factory1.createProductB();
const productB2 : AbstractProductB = factory2.createProductB();

抽象工廠與工廠方法不一樣

  1. 抽象工程關鍵在於產品之間的抽象關係,因此至少要兩個產品;工廠方法在於生成產品,不關注產品間的關係,因此能夠只生成一個產品。
  2. 抽象工廠中客戶端把產品的抽象關係理清楚,在最終使用的時候,通常使用客戶端,產品之間的關係是被封裝固定的;而工廠方法是在最終使用的時候,使用產品自己。
  3. 抽象工廠的工廠是類;工廠方法的工廠是方法。

抽象工廠的工廠類就作一件事情生產產品。生產的產品給客戶端使用,毫不給本身用。工廠方法生產產品,能夠給系統用,能夠給客戶端用,也能夠本身這個類使用。本身這個類除了這個工廠方法外,還能有其餘功能性的方法。

給工廠方法模式加一個客戶端,除了客戶端都不用這個建立者。這個時候建立者就是工廠類了。然而抽象工廠模式中,在客戶端內部編程時候,就能夠把工廠類看成建立者。

總結

抽象工廠模式的擴展有必定的開閉原則傾斜性,當增長一個新的產品族時只需增長一個新的具體工廠,不須要修改原代碼,知足開閉原則。當產品族中須要增長一個新種類的產品時,則全部的工廠類都須要進行修改,不知足開閉原則。另外一方面,當系統中只存在一個等級結構的產品時,抽象工廠模式將退化到工廠方法模式。

相關文章
相關標籤/搜索