經過前篇文章《設計模式:工廠模式,解除耦合的利器》的介紹,咱們對工廠模式有了深刻的瞭解,今天繼續介紹一種特殊的工廠模式,也就是抽象工廠模式。windows
抽象工廠模式:提供一個建立一系列相關或相互依賴對象的接口,而無須指定它們具體的類。抽象工廠模式又稱爲Kit模式,屬於對象建立型模式,是工廠方法模式的升級版,在有多個業務品種、業務分類時,經過抽象工廠模式產生須要的對象是一種很是好的解決方式。設計模式
抽象工廠模式包含了幾個角色:bash
AbstractFactory:用於聲明生成抽象產品的方法post
ConcreteFactory:實現了抽象工廠聲明的生成抽象產品的方法,生成一組具體產品,這些產品構成了一個產品族,每個產品都位於某個產品等級結構中;ui
AbstractProduct:爲每種產品聲明接口,在抽象產品中定義了產品的抽象業務方法;spa
Product:定義具體工廠生產的具體產品對象,實現抽象產品接口中定義的業務方法。操作系統
這是它的通用類圖: 設計
其中 AbstractProductA 和 AbstractProductB 就是兩個產品族的抽象類 (或者接口),而 Product1 和 Product2 就是產品族下的具體產品類,AbstractCreator 就是工廠的抽象。咱們能夠用操做系統來舉例,如今市面上用的最多的兩種PC端操做系統是windows和Linux,兩個系統都有共同類型的組件,如文件夾,按鈕,文本等。套用下抽象工廠的通用類圖,咱們不難發現,兩個系統就至關於產品組抽象類AbstractProductA 和 AbstractProductB,而按鈕、文本這些組件就是具體的產品類。code
而後再來分析一下,若是有一個應用要在兩個系統上運行,應該怎麼設計?是編寫兩套程序運行於不一樣的系統上?這樣實在是太浪費資源了,咱們能夠經過抽象工廠模式屏蔽掉操做系統對應用的影響。軟件功能、邏輯、UI 都一個很是相似,惟一的不一樣是調用不一樣的工廠方法,由不一樣的產品類去處理與操做系統交互的信息,而這就是抽象工廠的優點。cdn
抽象工廠的通用類圖咱們已經瞭解了,下面就是具體代碼的實現:
產品族的抽象類,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
複製代碼
總結下抽象工廠模式的特色,抽象工廠是全部形式的工廠模式中最爲抽象和最具通常性的一種形態,其優缺點大體以下:
一、隔離了具體類的生成,使得客戶並不須要知道什麼被建立,具備良好的封裝性。
二、橫向擴展容易。同個產品族若是須要增長多個 產品,只須要增長新的工廠類和產品類便可。
三、縱向擴展困難。若是增長新的產品組,抽象工廠類也要添加建立該產品組的對應方法,這樣一來全部的具體工廠類都要作修改了,嚴重違背了開閉原則。
參考: 《設計模式之禪》