工廠方法模式通過面向對象封裝了對象創(chuàng)建過程,實現(xiàn)低耦合、高內聚的代碼,給系統(tǒng)提供了靈活的產品擴展方式,是非常流行與常用的設計模式。
前面寫到簡單工廠模式雖然比較簡單,將實例的創(chuàng)建和使用分類,客戶端只需使用由工廠類創(chuàng)建的對象即可,無需關心對象的創(chuàng)建過程。但是這個系統(tǒng)仍然存在問題:
(相關資料圖)
1)工廠類過于龐大,包含了大量的if判斷語句代碼,導致維護和測試難度增加;
2)當前只存在一個工廠類,在需要添加新產品時,由于靜態(tài)工廠方法通過傳入參數(shù)創(chuàng)建不同的產品,必須修改工廠了的源碼,違背了開閉原則。
對此,需要對簡單工廠模式進行優(yōu)化,使其具有更好的靈活性和擴展性。這也是工廠方法模式的由來。
工廠方法模式(Factory Method Pattern)是簡單工廠模式的進一步抽象和推廣。在工廠方法模式中,不再提供一個統(tǒng)一的工廠類來創(chuàng)建所有的產品對象,而是針對不同產品提供不同的工廠,使每個工廠只負責創(chuàng)建對應的產品。
工廠方法模式,是對簡單工廠模式進行重構,即定義一個用于創(chuàng)建對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類。
工廠方法模式包含以下主要角色:
抽象工廠(Abstract Factory):提供了創(chuàng)建產品的接口,調用者通過它訪問產品。具體工廠(ConcreteFactory):實現(xiàn)了抽象工廠接口,完成具體產品的創(chuàng)建。抽象產品(Product):定義了產品的規(guī)范,描述了產品的主要特性和功能。具體產品(ConcreteProduct):實現(xiàn)了抽象產品角色所定義的接口,由具體工廠來創(chuàng)建,它同具體工廠之間往往存在依賴關系。工廠方法模式的主要優(yōu)點:
封裝了產品創(chuàng)建過程,調用者只需關心所需產品類型。實現(xiàn)了開閉原則,增加新產品無需修改之前工廠類代碼。調用者無需知道產品類名,實現(xiàn)解耦,符合依賴倒轉原則。易于擴展新產品,滿足開閉原則,增加新產品僅需新增一個具體產品類和具體工廠類,無需修改現(xiàn)存代碼。可能的缺點:
每增加一個產品就需要增加一個具體工廠,導致系統(tǒng)中類的個數(shù)成倍增加。復雜產品需要對應復雜工廠類,不易維護。我們使用 Typescript 代碼來實現(xiàn)一個簡單的工廠方法模式:
首先定義抽象產品類和具體產品類:
interface Food { getType(): string;}class Hamburger implements Food { getType() { return "Hamburger"; }}class Hotdog implements Food { getType() { return "Hotdog"; }}
然后是抽象工廠類和具體工廠類:
abstract class FoodFactory { abstract createFood(): Food;}class HamburgerFactory extends FoodFactory { createFood() { return new Hamburger(); }}class HotdogFactory extends FoodFactory { createFood() { return new Hotdog(); }}
客戶端代碼:
const hamburgerFactory = new HamburgerFactory();const hamburger = hamburgerFactory.createFood();const hotdogFactory = new HotdogFactory();const hotdog = hotdogFactory.createFood();
客戶端通過具體工廠來獲取需要的產品,不關心實際產品類名。
我們可以使用泛型來定義產品類型:
interface FoodFactory { createFood(): T; }// 實現(xiàn)時指定泛型class HamburgerFactory implements FoodFactory { // ...}
這樣可以使工廠方法返回類型更加明確。
工廠方法也可以簡單實現(xiàn)為函數(shù):
function createFood(type: "Hamburger" | "Hotdog") { switch(type) { case "Hamburger": return new Hamburger(); case "Hotdog": return new Hotdog(); }}
這種方式更簡單,降低了代碼的復雜度,但缺少面向對象的靈活性。
簡單工廠模式中工廠類負責所有產品的創(chuàng)建;而工廠方法模式中每一個具體工廠類只負責創(chuàng)建對應的一個產品,它將產品的創(chuàng)建推遲到子類。
兩者區(qū)別主要在:
簡單工廠中,工廠類負責所有產品創(chuàng)建。工廠方法中,每個具體工廠只負責對應的產品。工廠方法模式更加靈活,易擴展,但創(chuàng)建對象較多。簡單工廠適合產品種類少的情況,工廠方法適合產品不斷擴展的場景。
我們可以使用工廠方法模式實現(xiàn)一個游戲工廠,用于生成不同類型的游戲對象。
首先是游戲基類和具體游戲類:
interface Game { start();}class RPG implements Game { start() { console.log("Starting RPG game"); } }class MMORPG implements Game { start() { console.log("Starting MMORPG game"); }}
然后是抽象工廠和具體工廠:
abstract class GameFactory { abstract createGame(): Game;}class RPGFactory extends GameFactory { createGame() { return new RPG(); }}class MMORPGFactory extends GameFactory { createGame() { return new MMORPG(); }}
客戶端代碼:
const rpgFactory = new RPGFactory();const rpgGame = rpgFactory.createGame();rpgGame.start();const mmorpgFactory = new MMORPGFactory();const mmorpgGame = mmorpgFactory.createGame();mmorpgGame.start();
客戶端只需要關心游戲類型,而不關心具體類名。
工廠方法模式是一種廣泛使用的設計模式,它具有以下核心特點:
抽象工廠類負責定義創(chuàng)建對象的接口,而由子類實現(xiàn)CreateObject方法,實現(xiàn)了責任分解。每個具體工廠類只負責創(chuàng)建對應的一個產品,一個工廠類對應一個產品類。調用者只需要關心所需產品的類型,無需知道產品類名,實現(xiàn)了解耦。易于擴展新產品,滿足開閉原則,當新增產品時只要增加一個具體工廠和產品類,無需修改之前代碼。典型應用場景是針對同一抽象產品類有多個具體產品類的情況,而系統(tǒng)需要根據環(huán)境情況動態(tài)獲得不同的具體產品對象。相比簡單工廠模式,工廠方法模式更加靈活,易擴展,但創(chuàng)建對象較多。綜上,工廠方法模式通過面向對象封裝了對象創(chuàng)建過程,實現(xiàn)低耦合、高內聚的代碼,給系統(tǒng)提供了靈活的產品擴展方式,是非常流行與常用的設計模式。
[責任編輯:linlin]
標簽:
三言兩語說透設計模式的藝術-工廠方法模式
Google搜索技巧有哪些(google搜索技巧)
成都貝賽思國際學校學費多少錢(成都貝賽思國際學校學費多少錢一
高處不勝寒!謝治宇夫婦“撤退”之后,中際旭創(chuàng)還有多少空間?
售34.98萬元 騰勢D9新車型正式上市
75歲王剛現(xiàn)狀:白發(fā)老態(tài),兒子上初中,妻子風韻猶存
《行尸走肉》第11季的電臺會改變整個結局?誰能代替瑞克做決定?
大腿上線狀癬會變成白色的會引發(fā)白癜風嗎?
未來10年,美國債務每天增加52億美元!
現(xiàn)場深鏡頭|從落坡嶺回家的路
魈風輪兩立滿級(風輪兩立什么意思)
官方 : 米德爾斯堡前鋒霍普租借加盟圣何塞地震