抽象工廠模式
抽象工廠模式的用意
抽象工廠模式可以向客戶端提供一個接口,使得客戶端在不必指定產品的具體類型的情況下,創建多個產品族中的產品對象。這就是抽象工廠模式的用意。
系統的設計
採用抽象工廠模式設計出的系統類圖如下圖所示:
從上圖所示,抽象工廠涉及到以下角色:
- 抽象工廠(AbstractFactory)角色:擔任這個角色的是工廠方法模式的核心,它是與應用系統的商業邏輯無關的。通常使用 Java 接口或者抽象 Java 類實現,而所有的具體工廠類必須實現這個 Java 接口或繼承這個抽象 Java 類。
- 具體工廠類(Concrete Factory)角色:這個角色直接在客戶端的調用下創建產品的實例。這個角色含有選擇合適的產品對象的邏輯,而這個邏輯是與應用系統的商業邏輯緊密相關的。通常使用 Java 類實現這個角色。
- 抽象產品類(Abstract Product)角色:擔任這個角色的類是工廠方法模式所創建的對象的父類,或它們共同擁有的接口。通常使用 Java 接口或者抽象 Java 類實現這一角色。
- 具體產品類(Concrete Product)角色:抽象工廠模式所創建的任何產品對象都是某一個具體產品類的實例。這是客戶端最終需要的東西,其內部一定充滿了應用系統的商業邏輯。通常使用具體 Java 類實現這個角色。
下面利用相圖描述,會看到在相圖上出現兩個等級結構 A 和 B,以及兩個產品族 1 和 2,如下圖所示:
源代碼
抽象產品角色的源代碼
public interface Creator {
/**
* 產品等級結構A的工廠方法
*/
public ProductA factoryA();
/**
* 產品等級結構B的工廠方法
*/
public ProductB factoryB();
}
具體工廠類 ConcreteCreator1 和 ConcreteCreator2 的源代碼
public class ConcreteCreator1 implements Creator {
public ProductA factoryA() {
return new ProductA1();
}
public ProductB factoryB() {
return new ProductB1();
}
}
public class ConcreteCreator2 implements Creator {
public ProductA factoryA() {
return new ProductA2();
}
public ProductB factoryB() {
return new ProductB2();
}
}
一般而言,有多少個產品等級結構,就會在工廠角色中發現多少個工廠方法。每一個產品等級結構中有具體產品,就有多少個產品族,也就會在工廠等級結構中發現多少個具體工廠。
具體產品類 ProductA 的源代碼
客戶端需要的是產品,而不是工廠。在真實的系統中,產品類應當與應用系統的商業邏輯有密切關係。下面是產品等級結構 A 的抽象產品角色,在這個示意系統中,這個抽象產品角色是由一個 Java 接口實現的,如下代碼所示:
public interface ProductA {
}
可以看出這個接口也只是一個標識接口,下面展示其具體的實現類
具體產品類 ProductA1 和 ProductA2 的源代碼
public class ProductA1 implements Product {
public ProductA1() {
}
}
public class ProductA2 implements Product {
public ProductA2() {
}
}
而在這個演示系統中,產品等級結構B的源代碼和A大致相同,略。
談一談優劣:
優點:
分離接口和實現:
客戶端使用抽象工廠來創建需要的對象,而客戶端根本就不知道具體的實現是誰,客戶端只是面向產品的接口編程而已。也就是說,客戶端從具體的產品實現中解耦。使得切換產品族變得容易:因爲一個具體的工廠實現代表的是一個產品族,客戶端選用不同的工廠實現,就相當是在切換不同的產品族。
缺點:
不太容易擴展新的產品:
如果需要給整個產品族添加一個新的產品,那麼就需要修改抽象工廠,這一就會導致所有的工廠實現類都需要修改容易造成類層次複雜
來源《Java與模式》