雖然看完了《大話設計模式》,但是工廠模式的三種類型之間的差異,理解還不是非常透徹,那么本文就圍繞三者間的差異性來闡述各自的優缺點。
簡單工廠模式 (Simple Factory)
首先定義一個產品類的共同接口
public interface Product{
//價格
int price();
//產品名
String getName();
}
分別有三個產品ProductA、ProductB、ProductC ,均實現Product接口
ProductA
public class ProductA implements Product {
@Override
public int price() {
return 100;
}
@Override
public String getName() {
return "ProductA";
}
}
ProductB
public class ProductB implements Product {
@Override
public int price() {
return 200;
}
@Override
public String getName() {
return "ProductB";
}
}
ProductC
public class ProductC implements Product {
@Override
public int price() {
return 300;
}
@Override
public String getName() {
return "ProductC";
}
}
定義一個生產工廠類,根據輸入類型生產對應的產品
public class Factory {
/**
* 根據生產類型生產對應的產品
* @param type
* @return
*/
public static Product createProduct(String type){
Product product =null;
switch (type){
case "A":
product = new ProductA();
break;
case "B":
product = new ProductB();
break;
case "C":
product = new ProductC();
break;
}
return product;
}
}
根據輸入的生產類型生產對應的產品
Product productA = Factory.createProduct("A");
System.out.println("productA name="+productA.getName()+",getPrice:"+productA.getPrice());
Product productB = Factory.createProduct("B");
System.out.println("productB name="+productB.getName()+",getPrice:"+productB.getPrice());
Product productC = Factory.createProduct("C");
System.out.println("productC name="+productC.getName()+",getPrice:"+productC.getPrice());
輸出結果:
productA name=ProductA,getPrice:100
productB name=ProductB,getPrice:200
productC name=ProductC,getPrice:300
以上便是簡單工廠模式的一個典型事例,當用戶需要新增產品ProductD時,必須在工廠類的生產方法中增加對應的判斷分支,所以簡單工廠模式違背了開放封閉原則。
簡單工廠模式,利用靜態方法根據輸入參數生成對應的產品,隱藏了產品實例化的細節。
總結: 簡單工廠模式最大的優點在於工廠類中包含了必要的邏輯判斷,根據客戶端的選擇條件動態實例化相關的類,對於客戶端來說,去除了與具體產品的依賴。但是當需求變動的時候,需要對原有的類進行修改,違背了開放封閉原則。
工廠方法模式 (Factory Method)
通過工廠方法模式,可以解決簡單工廠模式的問題。
首先聲明一個工廠接口,所有工廠必須實現這個接口
public interface IFactory {
Product createProduct();
}
生產ProductA的工廠FactoryA
public class FactoryA implements IFactory {
@Override
public Product createProduct() {
return new ProductA();
}
}
生產ProductB的工廠FactoryB
public class FactoryB implements IFactory {
@Override
public Product createProduct() {
return new ProductB();
}
}
同樣地,生產ProductC的工廠FactoryC跟以上模式一樣。
現在來根據新的工廠方法模式來生產
IFactory factoryA = new FactoryA();
Product productA = factoryA.createProduct();
System.out.println("productA name="+productA.getName()+",getPrice:"+productA.getPrice());
IFactory factoryB = new FactoryB();
Product productB = factoryB.createProduct();
System.out.println("productB name="+productB.getName()+",getPrice:"+productB.getPrice());
IFactory factoryC = new FactoryB();
Product productC = factoryC.createProduct();
System.out.println("productC name="+productC.getName()+",getPrice:"+productC.getPrice());
輸出結果:
productA name=ProductA,getPrice:100
productB name=ProductB,getPrice:200
productC name=ProductC,getPrice:300
當需要增加一個新產品ProductD,只需要新建對應的FactoryD來實現生產功能即可,對原有的代碼沒有任何影響,非常符合開放封閉原則,但是由於每增加一個產品,都需要新增對應的生產工廠,導致增加額外的開發工作量。
總結:由於使用了多態,工廠方法克服了簡單工廠違背的開放封閉原則的缺點,又保持了封裝對象創建過程的優點。
抽象工廠模式 (Abstract Factory)
假設現在需要針對每種產品生產對應的贈品,難道我們要新增一個Gift的生產工廠嗎?其實沒有必要,因為在這個場景下,每種產品必須附帶了贈品,所以我們可以利用原有的工廠來生產贈品。
先定一個共同的Gift接口
public interface Gift {
String getGiftName();
}
增加GiftA、GiftB、GiftC
public class GiftA implements Gift {
@Override
public String getGiftName() {
return "GiftA";
}
}
修改Factory接口,增加生產Gift的方法
public interface IFactory {
Product createProduct();
Gift createGift();
}
修改工廠方法模式下的FactoryA、FactoryB、FactoryC
public class FactoryA implements IFactory {
@Override
public Gift createGift() {
return new GiftA();
}
@Override
public Product createProduct() {
return new ProductA();
}
}
生產產品和贈品
IFactory factoryA = new FactoryA();
Product productA = factoryA.createProduct();
Gift giftA = factoryA.createGift();
總結:抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口,而無需制定他們具體的類。抽象工廠接口,應該包含所有的產品創建的抽象方法,我們可以定義實現不止一個接口,一個工廠也可以生產不止一種產品類,和工廠方法模式一樣,抽象工廠模式同樣實現了開發封閉原則
原文鏈接:https://www.jianshu.com/p/d27d698802fd