通過前篇文章《設計模式:工廠模式,解除耦合的利器》的介紹,我們對工廠模式有了深入的瞭解,今天繼續介紹一種特殊的工廠模式,也就是抽象工廠模式。
定義
抽象工廠模式:提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於物件建立型模式,是工廠方法模式的升級版,在有多個業務品種、業務分類時,通過抽象工廠模式產生需要的物件是一種非常好的解決方式。
抽象工廠模式包含了幾個角色:
AbstractFactory:用於宣告生成抽象產品的方法
ConcreteFactory:實現了抽象工廠宣告的生成抽象產品的方法,生成一組具體產品,這些產品構成了一個產品族,每一個產品都位於某個產品等級結構中;
AbstractProduct:為每種產品宣告介面,在抽象產品中定義了產品的抽象業務方法;
Product:定義具體工廠生產的具體產品物件,實現抽象產品介面中定義的業務方法。
這是它的通用類圖:
其中 AbstractProductA 和 AbstractProductB 就是兩個產品族的抽象類 (或者介面),而 Product1 和 Product2 就是產品族下的具體產品類,AbstractCreator 就是工廠的抽象。
我們可以用作業系統來舉例,現在市面上用的最多的兩種PC端作業系統是windows和Linux,兩個系統都有共同型別的元件,如資料夾,按鈕,文字等。套用下抽象工廠的通用類圖,我們不難發現,兩個系統就相當於產品組抽象類AbstractProductA 和 AbstractProductB,而按鈕、文字這些元件就是具體的產品類。
然後再來分析一下,如果有一個應用要在兩個系統上執行,應該怎麼設計?是編寫兩套程式執行於不同的系統上?這樣實在是太浪費資源了,我們可以通過抽象工廠模式遮蔽掉作業系統對應用的影響。軟體功能、邏輯、UI 都一個非常類似,唯一的不同是呼叫不同的工廠方法,由不同的產品類去處理與作業系統互動的資訊,而這就是抽象工廠的優勢。
程式碼編寫
抽象工廠的通用類圖我們已經瞭解了,下面就是具體程式碼的實現:
產品族的抽象類,AbstractProductA 和 AbstractProductB,
public abstract class AbstractProductA {
//每個產品共有的方法
public void shareMethod() {
}
// 每個產品相同方法,不同實現
public abstract void doSomething();
}
public abstract class AbstractProductB {
//每個產品共有的方法
public void shareMethod() {
}
// 每個產品相同方法,不同實現
public abstract void doSomething();
}
兩個產品族的具體實現類程式碼,
public class ProductA1 extends AbstractProductA {
public void doSomething() {
System.out.println("我是產品A1");
}
}
public class ProductA2 extends AbstractProductA {
public void doSomething() {
System.out.println("我是產品A2");
}
}
public class ProductB1 extends AbstractProductB {
public void doSomething() {
System.out.println("我是產品B1");
}
}
public class ProductB2 extends AbstractProductB {
public void doSomething() {
System.out.println("我是產品B2");
}
}
抽象工廠類AbstractCreator
,有N個產品族,在抽象工廠類中就應該有N個建立方法。我們這裡定義兩個產品族的產品建立,程式碼如下:
public abstract class AbstractCreator {
//建立A產品
public abstract AbstractProductA createProductA();
//建立B產品
public abstract AbstractProductB createProductB();
}
然後是建立產品的具體工廠,有N個產品等級就應該有N個實現工廠類,在每個實現工廠中,實現不同產品族的生產任務。
public class Creator1 extends AbstractCreator {
public AbstractProductA createProductA() {
return new ProductA1();
}
public AbstractProductB createProductB() {
return new ProductB1();
}
}
public class Creator2 extends AbstractCreator {
public AbstractProductA createProductA() {
return new ProductA2();
}
public AbstractProductB createProductB() {
return new ProductB2();
}
}
到此為止,我們把所有的角色都建立出來了,最後設計一個場景類,驗證下是否能輸出對應產品的資訊,
public class Client {
public static void main(String[] args) {
//定義出兩個工廠
AbstractCreator creator1 = new Creator1();
AbstractCreator creator2 = new Creator2();
//產生A1物件
AbstractProductA a1 = creator1.createProductA();
//產生A2物件
AbstractProductA a2 = creator2.createProductA();
//產生B1物件
AbstractProductB b1 = creator1.createProductB();
//產生B2物件
AbstractProductB b2 = creator2.createProductB();
a1.doSomething();
a2.doSomething();
b1.doSomething();
b2.doSomething();
}
}
執行的結果為:
我是產品A1
我是產品A2
我是產品B1
我是產品B2
總結
總結下抽象工廠模式的特點,抽象工廠是所有形式的工廠模式中最為抽象和最具一般性的一種形態,其優缺點大致如下:
1、隔離了具體類的生成,使得客戶並不需要知道什麼被建立,具有良好的封裝性。
2、橫向擴充套件容易。同個產品族如果需要增加多個 產品,只需要增加新的工廠類和產品類即可。
3、縱向擴充套件困難。如果增加新的產品組,抽象工廠類也要新增建立該產品組的對應方法,這樣一來所有的具體工廠類都要做修改了,嚴重違背了開閉原則。
參考:
《設計模式之禪》