用烤肉來看工廠模式(下)

上一篇看完了情境,這一篇來說工廠模式的五大成分:

  1. 目的

  2. 時機

  3. 結構

  4. 角色

  5. 效果

簡單工廠模式

目的

利用傳入一個參數來取得不同的類別物件

時機

  • 當使用者只想要取得對應的物件,而不想知道細節如何建造時

  • 當一個方法過於肥大,且方法裡有物件初始化與其他商業邏輯時

  • 當一個物件初始化方法,被多個地方呼叫時

結構

simple factory

角色

  • Client:注入SimpleFactory,取得物件

  • SimpleFactory:依造參數生成各種物件

  • AbstractProduct:所有物件的抽象面

  • ConcreteProduct:各個具體物件

效果

優點

  1. 將建立物件的責任委派給工廠,客戶端不需要自己建立產品物件

  2. 客戶端不需要知道所有的類別名稱,只需知道要帶入的參數為何,對一些複雜的類別,可以因此減少使用者的記憶量

  3. 通過將參數放到設定檔,可以在不修改程式碼的情況下,更改使用的具體物件,提高了系統的靈活性

缺點

  1. 違反了開閉原則,只要有新的產品,就不得不改工廠的邏輯,不利於系統擴展及維護

  2. 簡單工廠邏輯如果出現bug,整個系統都會受影響

工廠方法模式

目的

定義一個建立物件的介面,但讓子類別去決定要實體化哪一種物件。工廠模式讓類別將實體化程序,交給子類別進行。

時機

  • 當類別無法明確指明欲建立的物件時

  • 當類別希望讓子類別去指定欲建立的物件類型時

  • 當類別將權力(複寫方法)下放給一個或多個用途的子類別,你又希望統一管理所有下放的權力

結構

factory method

角色

  • Product:定義factory method所造物件的介面

  • ConcreteProduct:具體實作Product介面的物件

  • Creator:宣告factory method,傳回Product型別之物件。預設傳回ConcreteProduct物件(也有可能會回傳Product物件)

  • ConcreteCreator:複寫factory method傳回具體的ConcreteProduct

效果

優點

  1. 工廠方法模式新增產品時,只需要增加對應的具體工廠和具體產品即可,符合「開閉原則」

  2. 工廠方法模式封裝了具體產品實作的細節,客戶只要關心對應的工廠即可

  3. 工廠方法模式可以先寫一個預設的factory method,替子類別預留掛勾(hook),讓子類別能藉以擴增功能

缺點

  1. 系統中類別成對增加,會增加系統的複雜度,提高維護的成本

  2. 由於考慮到系統的可擴展性,會在Creator層定義方法,增加系統的抽象性和理解度,提高系統的實現難度

Spring 應用

Spring使用工廠方法模式建立bean物件,透過BeanFactoryApplicationContext兩介面來實現。

  • BeanFactory:延緩注入(使用到某個bean時,才會注入),比ApplicationContext占用較少的記憶體,程式啟動速度快

  • ApplicationContext:容器啟動的時候,不管你用沒用到,一次性建立所有 bean 。

雖然BeanFactory看似效能較好,但ApplicationContext擴充了BeanFactory的所有功能,並提供其他額外功能,所以一般開發人員使用ApplicationContext居多。

抽象工廠模式

目的

以同一個介面來建立一整族相關或相依的物件,不須點明各物件真正所屬的具體類別

時機

  • 當系統必須要和最終成品的生成、組合、表達方式保持獨立時

  • 當系統組態必須能調整到與各陣營產品順利搭配時

  • 一整族相關的物件必須一快使用,你又得確保不會搭配錯誤時

  • 當你把程式庫貢獻出來,卻只想公開介面,不想公開實作細節時

結構

abstract factory

角色

  • AbstractFactory:宣告出可建構出產品族具體工廠的介面

  • ConcreteFactory:具體實作出可建構產品族的具體工廠

  • AbstractProduct:宣告產品族的介面

  • ConcreteProduct:具體實作出產品族底下的各個產品

  • Client:只與AbstractFactory和AbstractProduct兩抽象介面溝通

效果

優點

  1. 將具體類別關聯起來

  2. 易於將整個產品族物件抽換掉

  3. 增加成品物件的一致姓

缺點

  1. 產品族中想要新增新的產品是很困難的

總結

  • 簡單工廠: 用來生產同一等級結構中的任意產品。(對於增加新的產品,主要是新增產品,就要修改工廠類。符合單一職責原則。不符合開放-封閉原則)

  • 工廠方法:用來生產同一等級結構中的固定產品。(支持增加任意產品,新增產品時不需要更改已有的工廠,需要增加該產品對應的工廠。符合單一職責原則、符合開放-封閉原則。但是引入了複雜性)

  • 抽象工廠:用來生產不同產品族的全部產品。(增加新產品時,需要修改工廠,增加產品族時,需要增加工廠。符合單一職責原則,部分符合開放-封閉原則,降低了複雜性)

三種工廠方式有各自的使用時機與優缺點,依需求尋找最合適的,才是最好的。