結構
- Product(抽象產品):它是定義產品的接口,是工廠方法模式所創建對象的超類型,也就是產品對象的公共父類。
- ConcreteProduct(具體產品):它實現了抽象產品接口,某種類型的具體產品由專門
的具體工廠創建,具體工廠和具體產品之間一對應。 - Factory(抽象工廠):在抽象工廠類中聲明瞭工廠方法(Factory Method),用於返回一個產品。抽象工廠是工廠方法模式的核心,所有創建對象的工廠類都必須實現該接口。
- ConcreteFactory(抽象工廠):它是抽象工廠類的子類,實現了在抽象工廠中聲明的工廠方法,並可以由客戶端調用,返回一個具體產品的實例。
代碼
抽象產品
public interface Product {
void productMethod();
}
具體產品A
public class ConcreteProductA implements Product {
@Override
public void productMethod() {
System.out.println("ConcreteProductA");
}
}
具體產品B
public class ConcreteProductB implements Product {
@Override
public void productMethod() {
System.out.println("ConcreteProductB");
}
}
抽象工廠
public interface Factory {
Product factoryMethod();
}
具體工廠A
public class ConcreteFactoryA implements Factory{
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}
具體產品B
public class ConcreteFactoryB implements Factory{
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}
客戶端調用
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.factoryMethod();
productA.productMethod();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.factoryMethod();
productB.productMethod();
}
}
擴展
新建具體產品C
public class ConcreteProductC implements Product {
@Override
public void productMethod() {
System.out.println("ConcreteProductC");
}
}
新建具體工廠C
public class ConcreteFactoryC implements Factory{
@Override
public Product factoryMethod() {
return new ConcreteProductC();
}
}
調用
Factory factoryC = new ConcreteFactoryC();
Product productC = factoryC.factoryMethod();
productC.productMethod();
優/缺點與使用環境
- 優點
- 在工廠方法模式中,工廠方法用創建客戶端所需要的產品,同時還向客戶端隱藏了哪種具體產品類將被實例化這一細節,用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無需知道具體產品類的類名。
- 基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它能夠讓工廠自 主確定創建何種產品對象,而如何創建這個對象的細節完全封裝在具體工廠內部。工廣方法模式之所以又被稱爲多態工廠模式,正是因爲所有的具體工廠類都具有同一抽象父類
- 使用工廠方法模式的另一個優點是在系統中加入新產品時無須修改抽象工廠和 抽象產品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產品。而只要添加一個具體工廠和具體產品類,這樣系統的擴展性也就變得非常好,完全符合開閉原則。
- 缺點
- 在添加新產品時需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類, 系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。
- 由於考慮到系統的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度。
- 適用環境
- 客戶端不知道它所需要的對象的類。在工廠方法模式中,客戶端不需要知道具體 產品類的類名,只需要知道所對應的工廠即可,具體產品對象由具體工廠類創建,可將具體工廠類的類名存儲在配置文件或數據庫中。
- 抽象工廠類通過其子類來指定創建哪個對象。在工廠方法模式中,對於抽象工廠 類只需要提供一個創建產品的接口,而由其子類來確定具體要創建的對象.利用面向對象的多態性和里氏代換原則,在程序運行時子類對象將覆蓋父類對象,從而使得系統更容易擴展。