掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
前面寫到簡單工廠模式雖然比較簡單,將實(shí)例的創(chuàng)建和使用分類,客戶端只需使用由工廠類創(chuàng)建的對象即可,無需關(guān)心對象的創(chuàng)建過程。但是這個(gè)系統(tǒng)仍然存在問題:

1)工廠類過于龐大,包含了大量的if判斷語句代碼,導(dǎo)致維護(hù)和測試難度增加;
2)當(dāng)前只存在一個(gè)工廠類,在需要添加新產(chǎn)品時(shí),由于靜態(tài)工廠方法通過傳入?yún)?shù)創(chuàng)建不同的產(chǎn)品,必須修改工廠了的源碼,違背了開閉原則。
對此,需要對簡單工廠模式進(jìn)行優(yōu)化,使其具有更好的靈活性和擴(kuò)展性。這也是工廠方法模式的由來。
工廠方法模式(Factory Method Pattern)是簡單工廠模式的進(jìn)一步抽象和推廣。在工廠方法模式中,不再提供一個(gè)統(tǒng)一的工廠類來創(chuàng)建所有的產(chǎn)品對象,而是針對不同產(chǎn)品提供不同的工廠,使每個(gè)工廠只負(fù)責(zé)創(chuàng)建對應(yīng)的產(chǎn)品。
工廠方法模式,是對簡單工廠模式進(jìn)行重構(gòu),即定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪個(gè)類。工廠方法使一個(gè)類的實(shí)例化延遲到其子類。
工廠方法模式包含以下主要角色:
工廠方法模式的主要優(yōu)點(diǎn):
可能的缺點(diǎn):
我們使用 Typescript 代碼來實(shí)現(xiàn)一個(gè)簡單的工廠方法模式:
首先定義抽象產(chǎn)品類和具體產(chǎ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();客戶端通過具體工廠來獲取需要的產(chǎn)品,不關(guān)心實(shí)際產(chǎn)品類名。
我們可以使用泛型來定義產(chǎn)品類型:
interface FoodFactory {
createFood(): T;
}
// 實(shí)現(xiàn)時(shí)指定泛型
class HamburgerFactory implements FoodFactory {
// ...
} 這樣可以使工廠方法返回類型更加明確。
工廠方法也可以簡單實(shí)現(xiàn)為函數(shù):
function createFood(type: 'Hamburger' | 'Hotdog') {
switch(type) {
case 'Hamburger':
return new Hamburger();
case 'Hotdog':
return new Hotdog();
}
}這種方式更簡單,降低了代碼的復(fù)雜度,但缺少面向?qū)ο蟮撵`活性。
簡單工廠模式中工廠類負(fù)責(zé)所有產(chǎn)品的創(chuàng)建;而工廠方法模式中每一個(gè)具體工廠類只負(fù)責(zé)創(chuàng)建對應(yīng)的一個(gè)產(chǎn)品,它將產(chǎn)品的創(chuàng)建推遲到子類。
兩者區(qū)別主要在:
簡單工廠適合產(chǎn)品種類少的情況,工廠方法適合產(chǎn)品不斷擴(kuò)展的場景。
我們可以使用工廠方法模式實(shí)現(xiàn)一個(gè)游戲工廠,用于生成不同類型的游戲?qū)ο蟆?/p>
首先是游戲基類和具體游戲類:
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();客戶端只需要關(guān)心游戲類型,而不關(guān)心具體類名。
工廠方法模式是一種廣泛使用的設(shè)計(jì)模式,它具有以下核心特點(diǎn):
綜上,工廠方法模式通過面向?qū)ο蠓庋b了對象創(chuàng)建過程,實(shí)現(xiàn)低耦合、高內(nèi)聚的代碼,給系統(tǒng)提供了靈活的產(chǎn)品擴(kuò)展方式,是非常流行與常用的設(shè)計(jì)模式。

我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流