定義:工廠模式專門負責將大量有共同接口的類實例化。工廠模式可以動態決定將哪一個類實例化,而不必事先知道每次要實例化哪一個類。
三種形態:
- 簡單工廠模式:又稱靜態工廠方法
- 工廠方法模式:又稱多態性工廠模式或虛擬構造子模式
- 抽象工廠模式:又稱工具箱模式
簡單工廠模式:專門定義一個類來負責其他類的實例,被創建的實例通常具有共同的父類或接口。
適用場景:
- 工廠類負責創建的對象比較少:由於創建的對象比較少,不會造成工廠方法中的業務邏輯太過復雜;
- 客戶端只知道傳入工廠類的參數,對於如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,只需要知道類型所對應的參數;
優點:
- 工廠類含有必要的邏輯判斷,可以決定什么時候創建哪一個產品實例,客戶端可以免除直接創建產品對象的責任,而僅僅“消費”產品:簡單工廠模式通過這種做法實現了對責任的分割,它提供了專門的工廠類用於創建對象;
- 客戶端無需知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些復雜的類名,通過簡單工廠模式可以減少使用者的記憶量;
- 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程序上提高了系統的靈活性。
缺點:
- 由於工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都要受到影響;
- 使用簡單工廠模式將會增加系統中類的個數,在一定程度上增加了系統的復雜度和理解難度;
- 系統擴展困難,一旦添加新產品,就不得不修改工廠邏輯,在產品類型較多時有可能造成工廠邏輯過於復雜不利於系統的擴展和維護;
- 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。
工廠方法模式:定義一個用於創建對象的接口,讓子類決定實例化哪一個類,工廠方法使一個類的實例化延遲到其子類。
在工廠方法模式中,核心的工廠類不再負責所有的產品的創建,而是將具體創建的工作子類去做,這個核心類則成為了一個抽象工廠角色,僅負責給出具體工廠子類必須實現的接口,而不接觸哪一個產品類應當被實例化這種細節。
適用場景:
- 一個類不知道它所需要的對象的類:在工廠方法模式中,客戶端不需要指定具體產品類的類名,只需要知道所對應的工廠即可,具體的產品對象由具體工廠類創建;客戶端只需要知道創建具體產品的工廠類;
- 一個類通過其子類來指定創建哪個對象:在工廠方法模式中,對於抽象工廠類只需要提供一個創建產品的接口,而由其子類來確定具體要創建的對象,利用面向對象的多態性和里氏替換原則,在程序運行時,子類對象將覆蓋父類對象,從而使得系統更容易擴展;
- 將創建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時無需關心哪一個工廠子類創建產品,需要時再動態指定,可將具體工廠類的類名存儲在配置文件或數據庫中。
優點:
- 在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏具體產品類將被實例化這一細節,用戶只需關心所需產品對應的工廠,無需關心創建細節,甚至無需知道具體產品類的類名;
- 基於工廠角色和產品角色多態性的設計是工廠方法模式的關鍵,它能夠使工廠自主確定創建何種產品對象,而如何創建這個對象的細節則完全封裝到具體工廠內部。工廠方法模式,又稱為多態性工廠模式,正是因為所有的具體工廠類都具有同一抽象父類;
- 使用工廠方法模式在系統中加入新產品時,無需修改抽象工廠和抽象產品提供的接口,無需修改客戶端,也無需修改其它的具體工廠和具體產品,而只需要添加一個具體工廠和具體產品就可以了,這樣,系統的可擴展性也就變得非常好,完全符合“開閉原則”。
缺點:
- 在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數成對增加,在一定程度上增加了系統的復雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷;
- 由於考慮到系統的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到反射機制等技術,增加了系統的實現難度。
抽象工廠模式:提供一個創建一系列或相互依賴的對象的接口,而無需指定它們的具體類。
適用場景:
- 一個系統不應當依賴於產品類實例如何被創建、組合和表達的細節,這對於所有形態的工廠模式都是重要的;
- 一個系統有多於一個產品族,而系統只消費其中某一族產品;
- 同屬於同一個產品族的產品是在一起使用的,這一約束必須要在系統的設計中體現出來;
- 系統提供一個產品類的庫,所有的產品以相同的接口出現,從而使客戶端不依賴於實現;
優點:
- 隔離了具體類的創建,使得用戶不需要知道創建的細節;
- 當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用一個產品族中的對象;
缺點:
- 添加新的產品對象時,難以擴展抽象工廠以便生成新種類的產品;