簡單工廠設計模式---透徹講解
一. 什麼是工廠
理解簡單工廠設計模式, 首先要理解什麼是工廠. 我們身邊有很多工廠. 釀酒的酒廠, 製衣的衣廠, 加工肉類的肉加工廠等等. 這些工廠他們到底是怎麼釀酒的? 怎麼製衣的?怎麼加工肉的? 我們並不知道, 也不需要知道. 不知道並不影響我們喝酒, 穿衣, 吃肉. 這就是工廠的特點之一: 客戶不需要知道怎麼做的, 但是不影響使用
再來看看工廠的第二個特點: 比如肉加工廠---雙匯. 牛肉進去出來牛肉火腿腸, 羊肉進去出來羊肉火腿腸, 豬肉進去出來豬肉火腿腸. 我不需要知道怎麼加工的, 我只需要把材料扔進去, 然後對應的火腿腸就出來了. 這就是第二個特點: 給你材料, 你去製造出我想要的東西, 至於怎麼做, 我並不關心.
程式中的工廠也是一樣的思想. **工廠的作用就是創造物件. **
二. 簡單工廠設計模式
2.1. 設計模式
我們基本都知道設計模式有23種, 說到這, 我們先來說說設計模式。
設計模式不是語法, 而是一種巧妙的寫法, 能夠把程式變得更加靈活的寫法.
設計模式有三種: 建立型, 行為型, 結構型. 簡單工廠設計模式屬於建立型. 但簡單工廠設計模式不屬於23種設計模式範圍內, 屬於23種設計模式中工廠設計模式裡最簡單的一種.
2.2. 簡單工廠設計模式
簡單工廠設計模式, 又叫做靜態工廠設計模式. 簡單工廠設計模式提供一個建立物件例項的功能,而無需關係其具體實現,被建立例項的型別可以是介面、抽象類,也可以是具體的類。
2.3. 簡單工廠設計模式的4要素
這個很重要, 這也是建立一個簡單工廠的步驟
- API介面: 建立一個API介面或抽象類
- Impl實現類: 一個或多個實現API介面/抽象類的類
- 工廠: 定義一個工廠, 用來建立API介面類物件
- 客戶端: 用來呼叫工廠建立API介面或抽象類的客戶端
2.4 簡單工廠結構型別及說明
以上型別就描述了一個簡單工廠建立的整個過程
第一步: 定義API介面或抽象類, 並定義一個operate操作方法
第二步: 定義API的實現類, 每個實現類單獨實現operate方法
第三步: 定義工廠類. 工廠類依賴API介面和API的實現類, 簡單工廠設計模式是建立型的, 通常是用來建立實體類. 因此我們定義一個create方法, 來建立例項物件,入參通常是一個指定的型別
第四步: 定義客戶端. 客戶端傳入一個指定的型別給工廠, 工廠就會建立出對應的實現類.
2.5 簡單工廠模板程式碼
第一步: 製衣廠API介面
package com.lxl.www.designPatterns.simpleFactory.demo;
public interface IClothes {
void operate();
}
第二步: 製衣廠API實現類
ManClothes: 製作男士衣服
package com.lxl.www.designPatterns.simpleFactory.demo;
public class ManClothes implements IClothes{
@Override
public void operate() {
System.out.println("製作男人的衣服");
}
}
WomenClothes: 製作女士衣服
package com.lxl.www.designPatterns.simpleFactory.demo;
public class WomenClothes implements IClothes{
@Override
public void operate() {
System.out.println("製作女人的衣服");
}
}
ChildClothes: 製作兒童衣服
package com.lxl.www.designPatterns.simpleFactory.demo;
public class ChildClothes implements IClothes{
@Override
public void operate() {
System.out.println("製作兒童的衣服");
}
}
第三步: 定義工廠, 並建立衣服類介面
package com.lxl.www.designPatterns.simpleFactory.demo;
/**
* 製衣工廠
*/
public class ClothesFactory {
public static IClothes createClothes(String type) {
if (type.equals("男人")) {
return new ManClothes();
} else if (type .equals("女人")) {
return new WomenClothes();
} else {
return new ChildClothes();
}
}
}
第四步: 定義客戶端, 指定製衣類別, 製衣.
public static void main(String[] args) {
IClothes manClothes = ClothesFactory.createClothes("男人");
manClothes.operate();
}
2.6 簡單工廠命名建議
- 類命名建議為“模組名稱+Factory”,比如,使用者模組的工廠就稱為UserFactory, 製衣工廠: ClothesFactory
- 方法名稱通常為“get+介面名稱”或者是“create+介面名稱”。比如製衣介面名稱為IClothes,那麼方法名稱通常為getClothes或者createClothes。
提供一個建立物件例項的功能,而無需關心其具體實現,被建立例項的型別可以是介面、抽象類,也可以是具體的類。
2.7 總結
簡單工廠方法的內部主要實現的功能是 ** “選擇合適的實現類” **,選擇條件或者是引數的來源通常為以下幾種:
- 來源於客戶端,由Client來傳入引數
- 來源於配置檔案,從配置檔案獲取用於判斷的值
- 來源於程式執行期的某個值,比如從快取中獲取某個執行期的值
三. 簡單工廠的優缺點
優點:
- 幫助封裝: 簡單工廠雖然簡單,但是非常友好地幫助我們實現了元件的封裝,然後讓元件外部能真正面向介面程式設計。
- 解耦: 通過簡單工廠,實現了客戶端和具體實現類的解耦。
- 把初始化例項時的工作放到工廠裡進行,使程式碼更容易維護。 更符合物件導向的原則 & 面向介面程式設計,而不是面向實現程式設計。
缺點:
1.可能增加客戶端的複雜度
2.不方便擴充套件子工廠
3. 工廠類集中了所有例項(產品)的建立邏輯,一旦這個工廠不能正常工作,整個系統都會受到影響;
4. 違背“開放 - 關閉原則”,一旦新增新產品就不得不修改工廠類的邏輯,這樣就會造成工廠邏輯過於複雜。
5. 簡單工廠模式由於使用了靜態工廠方法,靜態方法不能被繼承和重寫,會造成工廠角色無法形成基於繼承的等級結構。
四. 使用場景
- 如果想完全封裝隔離具體實現,讓外部只能通過介面來操作封裝體,那麼可以選擇簡單工廠,讓客戶端通過工廠來獲取相應的介面,而無須關心具體的實現。
- 如果想要把對外建立物件的職責集中管理和控制,可以選擇簡單工廠。
- 當工廠類負責建立的物件(具體產品)比較少時。