### 工廠模式 工廠模式是一種創建者設計模式,細分之下可以分成三類`簡單工廠模式`,`工廠方法模式`和`抽象工廠模式`。 #### 簡單工廠模式 最簡單的工廠模式,它採用靜態方法的方式來決定應該應該生產什麼商品。 ```java public class StoreFactory { public ...
工廠模式
工廠模式是一種創建者設計模式,細分之下可以分成三類簡單工廠模式
,工廠方法模式
和抽象工廠模式
。
簡單工廠模式
最簡單的工廠模式,它採用靜態方法的方式來決定應該應該生產什麼商品。
public class StoreFactory {
public static ICommodity getCommodityService(Integer commodityType) {
if (null == commodityType) {
return null;
}
switch (commodityType) {
case 1:
return new CouponCommodityService();
case 2:
return new GoodsCommodityService();
case 3:
return new CardCommodityService();
}
throw new RuntimeException("不存在的商品服務類型");
}
}
它的優點在於
- 將創建實例的工作與使用實例的工作分開,使用者不必關心類對象如何創建,實現瞭解耦
- 把初始化實例時的工作放到工廠里進行,使代碼更容易維護,更符合面向對象的原則
面向介面編程,而不是面向實現編程
它的缺點在於
- 工廠類集中了所有實例的創建邏輯,一旦這個工廠不能正常工作,整個系統都會受到影響
- 違背
開閉原則
,一旦添加新的產品就不得不修改工廠類的邏輯,這樣就會造成工廠邏輯過於複雜 - 簡單工廠模式使用了靜態工廠方法,靜態方法不能被繼承和重寫,會造成工廠角色無法形成基於繼承的等級結構
它適用於
- 客戶只知道傳入工廠類的參數,對於如何創建對象的邏輯不關心時;
- 當工廠類負責創建的對象比較少時。
工廠方法模式
工廠方法模式
中,工廠父類負責定義創建對象的公共介面,而子類則負責生成具體的對象。
它把類的實例化延遲到工廠類的子類中,由子類來決定應該實例化哪個類。
由此,它解決了簡單工廠模式違背了開閉原則
的問題。
它的優點在於
- 更符合
開閉原則
- 符合
單一責任原則
,每個具體工廠類只負責創建對應的產品 - 不使用靜態工廠方法,可以形成基於繼承的等級結構
它的缺點在於
- 需要的類的數量非常多,每添加一個新產品,就要相應的添加一個新的工廠。
- 雖然保證了工廠方法內的對修改關閉,但對於使用工廠方法的類,如果要更換另一種產品,仍然需要修改實例化的具體工廠類
- 一個工廠只能創建一種具體產品
它適用於:
- 當一個類不需要知道它所需要的對象的類時
- 當一個類希望通過其子類來指定創建對象時
- 將創建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時無須關心是哪一個工廠子類創建產品子類,需要時再動態指定,可將具體工廠的類名存儲在配置文件或資料庫中(比如spring中的FactoryBean)
抽象工廠模式
抽象工廠模式
定義了一個能生產一個產品族
的超級抽象工廠,然後交給子類工廠去生產某一個產品族
的產品。
產品族和產品等級
產品等級結構
既是產品的繼承結構。比如一個抽象類是電視機,其子類有海爾電視機、TCL電視機,則抽象電視機與具體品牌的電視機之間構成了一個產品等級結構。
產品族
是指由同一個工廠生產的,位於不同產品等級結構中的一組產品,如海爾生產的海爾電視機、海爾洗衣機和海爾冰箱,構成了一個產品族。
設計模式詳解
圖中,IProductFactory
是工廠介面,定義了生產手機和路由器組成的產品族的方法。而子類工廠HuaweiFactory
負責生產華為產品族,XiaomiFactory
負責生產小米產品族。
另外,IPhoneProduct
和IRouterProduct
分別定義了手機和路由器兩個產品等級。
它的優點在於
- 一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象
- 可以很方便地添加一個新的產品族
它的缺點在於
- 產品族的拓展非常困難,要增加一個系列的某一個產品,既要修改工廠抽象類里添加代碼,又要在具體的實現類裡面添加代碼
- 增加了系統的抽象性和理解難度
它適用於
- 一系列相關產品對象(屬於同一產品族)一起創建時需要大量的重覆代碼
- 提供一個產品類的庫,所有的產品以同樣的介面出現,從而使得客戶端不依賴於具體的實現