設(shè)計模式-3種工廠模式

工廠模式包括:簡單工廠模式,工廠方法模式伍宦,抽象工廠模式

簡單工廠模式

工廠方法根據(jù)參數(shù)直接創(chuàng)建實例:工廠->產(chǎn)品

一個人開了個咖啡館芽死,賣2種咖啡:美式咖啡、拿鐵次洼。

class AmericanoCoffee {
    constructor() {
        console.log('AmericanoCoffee');
    }
}
class LatteCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
function createCoffeeFactory(name: string) {
    switch (name) {
        case 'AmericanoCoffee':
            return new AmericanoCoffee();
        case 'LatteCoffee':
            return new LatteCoffee();
        default:
            return new Error('本店不支持');
    }
}
// 簡單工廠:工廠方法直接創(chuàng)建實例
createCoffeeFactory('AmericanoCoffee');
createCoffeeFactory('LatteCoffee');

代碼非常簡單关贵,但是如果新增一樣咖啡時,要擴展一個咖啡種類Cuppuccino卖毁,同時createCoffeeFactory的switch里面要新增一個case坪哄。
違法開閉原則:對擴展開發(fā),對修改關(guān)閉。什么是擴展翩肌,什么是修改?

// 新增一個類CuppuccinoCoffee禁悠,就是擴展
class CuppuccinoCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
function createCoffeeFactory(name: string) {
    switch (name) {
        case 'AmericanoCoffee':
            return new AmericanoCoffee();
        case 'LatteCoffee':
            return new LatteCoffee();
        case 'CuppuccinoCoffee': // 修改了原有的代碼念祭,就是修改
            return new CuppuccinoCoffee()
        default:
            return new Error('本店不支持');
    }
}
createCoffeeFactory('CuppuccinoCoffee');

工廠方法模式

抽象一個工廠方法,具體的工廠創(chuàng)建產(chǎn)品
抽象工廠->具體工廠->一種產(chǎn)品

class AmericanoCoffee {
    constructor() {
        console.log('AmericanoCoffee');
    }
}
class LatteCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
// 抽象工廠
abstract class CoffeeFactory {
    abstract createCoffee();
}
// 具體工廠
class AmericanoCoffeeFactory extends CoffeeFactory {
    createCoffee() {
        new AmericanoCoffee()
    }
}
class LatteCoffeeFactory extends CoffeeFactory {
    createCoffee() {
        new LatteCoffee();
    }
}
// 具體工廠創(chuàng)建產(chǎn)品
new AmericanoCoffeeFactory().createCoffee();
new LatteCoffeeFactory().createCoffee();

此時碍侦,如果要增加卡布奇諾咖啡粱坤,要擴展一個工廠和一種咖啡

// 擴展一個咖啡
class CuppuccinoCoffee{
    constructor() {
        console.log('LatteCoffee');
    }
}
// 擴展一個工廠
class CuppuccinoCoffeeFactory extends CoffeeFactory {
    createCoffee() {
        new CuppuccinoCoffee();
    }
}
// 客戶端下單卡布奇諾
new CuppuccinoCoffeeFactory().createCoffee();

相比簡單工廠模式,克服了簡單工廠的缺點瓷产。

抽象工廠模式

但是假如這家咖啡廳是星巴克,客人要點瑞幸的咖啡時,怎么辦首妖?
我們把咖啡分成:星巴克美式炫贤,星巴克拿鐵,瑞幸美式尔邓,瑞幸拿鐵
和工廠方法對區(qū)別晾剖,增加對咖啡種類進行抽象。這里涉及到產(chǎn)品族和產(chǎn)品種類的概念梯嗽。
星巴克和瑞幸是產(chǎn)品族齿尽,美式和拿鐵是產(chǎn)品種類。是2個維度的概念灯节。
抽象產(chǎn)品->實現(xiàn)產(chǎn)品
抽象工廠->實現(xiàn)工廠->生產(chǎn)多種產(chǎn)品

// 和工廠方法模式的區(qū)別:對咖啡種類進行抽象
abstract class AmericanoCoffee {
}
abstract class LatteCoffee{
}

class StarbuckAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('StarbuckAmericanoCoffee');
    }
}
class StarbuckLatteCoffee extends LatteCoffee{ 
    constructor() {
        super();
        console.log('StarbuckLatteCoffee');
    }
}
class LuckinAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('LuckinAmericanoCoffee');
    }
}
class LuckinLatteCoffee extends LatteCoffee{
    constructor() {
        super();
        console.log('LuckinLatteCoffee');
    }
}
// 和工廠方法模式的區(qū)別:一個工廠要做2種咖啡
abstract class CoffeeFactory {
    abstract createAmericanoCoffee();
    abstract createLattaCoffee();
}

class StarbuckCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new StarbuckAmericanoCoffee();
    }
    createLattaCoffee() {
        new StarbuckLatteCoffee();
    }
}
class LuckinCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new LuckinAmericanoCoffee();
    }
    createLattaCoffee() {
        new LuckinLatteCoffee();
    }
}

new StarbuckCoffeeFactory().createAmericanoCoffee();
new StarbuckCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createAmericanoCoffee();
new LuckinCoffeeFactory().createLattaCoffee();

此時要增加卡布奇諾咖啡種類,那么要擴展CuppuccinoCoffee抽象類循头,兩個產(chǎn)品族分別擴展CuppuccinoCoffee實現(xiàn)類,抽象工廠要增加(修改)做卡布奇諾的抽象方法炎疆,具體工廠要增加(修改)做卡布奇諾的實現(xiàn)方法卡骂。
此時,抽象工廠的缺點也暴露出來磷雇。增加一個產(chǎn)品種類時偿警,擴展有1+n個,修改有1+n個唯笙。n是產(chǎn)品族的個數(shù)

abstract class AmericanoCoffee {
}
abstract class LatteCoffee{
}
// 擴展咖啡種類
abstract class CuppuccinoCoffee{
}

class StarbuckAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('StarbuckAmericanoCoffee');
    }
}
class StarbuckLatteCoffee extends LatteCoffee{ 
    constructor() {
        super();
        console.log('StarbuckLatteCoffee');
    }
}
// 星巴克擴展
class StarbuckCuppuccinoCoffee extends CuppuccinoCoffee{ 
    constructor() {
        super();
        console.log('StarbuckCuppuccinoCoffee');
    }
}
// 瑞幸擴展
class LuckinAmericanoCoffee extends AmericanoCoffee{
    constructor() {
        super();
        console.log('LuckinAmericanoCoffee');
    }
}
class LuckinLatteCoffee extends LatteCoffee{
    constructor() {
        super();
        console.log('LuckinLatteCoffee');
    }
}
class LuckinCuppuccinoCoffee extends CuppuccinoCoffee{
    constructor() {
        super();
        console.log('LuckinCuppuccinoCoffee');
    }
}

abstract class CoffeeFactory {
    abstract createAmericanoCoffee();
    abstract createLattaCoffee();
    // 增加抽象方法
    abstract createCuppuccinoCoffee();
}

class StarbuckCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new StarbuckAmericanoCoffee();
    }
    createLattaCoffee() {
        new StarbuckLatteCoffee();
    }
    // 增加實現(xiàn)方法
    createCuppuccinoCoffee(){
        new StarbuckCuppuccinoCoffee();
    }
}
class LuckinCoffeeFactory extends CoffeeFactory {
    createAmericanoCoffee() {
        new LuckinAmericanoCoffee();
    }
    createLattaCoffee() {
        new LuckinLatteCoffee();
    }
    // 增加實現(xiàn)方法
    createCuppuccinoCoffee(){
        new LuckinCuppuccinoCoffee();
    }

}

new StarbuckCoffeeFactory().createAmericanoCoffee();
new StarbuckCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createAmericanoCoffee();
new LuckinCoffeeFactory().createLattaCoffee();
new LuckinCoffeeFactory().createCuppuccinoCoffee();

總結(jié):

  1. 簡單工廠模式:
    工廠-產(chǎn)品
    優(yōu)點:簡單
    缺點:違法開閉原則
  2. 工廠方法模式:
    抽象工廠-實現(xiàn)工廠-一種產(chǎn)品
    優(yōu)點:克服簡單工廠的缺點
    缺點:面對產(chǎn)品族和產(chǎn)品種類問題時螟蒸,不夠抽象
  3. 抽象工廠模式:
    抽象產(chǎn)品-具體產(chǎn)品
    抽象工廠-具體工廠-多種產(chǎn)品
    優(yōu)點:針對多個產(chǎn)品族和多個產(chǎn)品種類時,相對來說能抽象清晰的表達多個維度的關(guān)系崩掘;拓展產(chǎn)品族時七嫌,遵循開閉原則
    缺點:擴展產(chǎn)品種類時,無法很好地做到開閉原則苞慢。需要1+n個修改
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末诵原,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绍赛,老刑警劉巖蔓纠,帶你破解...
    沈念sama閱讀 216,496評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異吗蚌,居然都是意外死亡腿倚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評論 3 392
  • 文/潘曉璐 我一進店門蚯妇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來敷燎,“玉大人,你說我怎么就攤上這事箩言∮补幔” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評論 0 353
  • 文/不壞的土叔 我叫張陵陨收,是天一觀的道長饭豹。 經(jīng)常有香客問我,道長畏吓,這世上最難降的妖魔是什么墨状? 我笑而不...
    開封第一講書人閱讀 58,180評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮菲饼,結(jié)果婚禮上肾砂,老公的妹妹穿的比我還像新娘。我一直安慰自己宏悦,他們只是感情好镐确,可當(dāng)我...
    茶點故事閱讀 67,198評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著饼煞,像睡著了一般源葫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上砖瞧,一...
    開封第一講書人閱讀 51,165評論 1 299
  • 那天息堂,我揣著相機與錄音,去河邊找鬼块促。 笑死荣堰,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的竭翠。 我是一名探鬼主播振坚,決...
    沈念sama閱讀 40,052評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼斋扰!你這毒婦竟也來了渡八?” 一聲冷哼從身側(cè)響起啃洋,我...
    開封第一講書人閱讀 38,910評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎屎鳍,沒想到半個月后宏娄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡逮壁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,542評論 2 332
  • 正文 我和宋清朗相戀三年绝编,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片貌踏。...
    茶點故事閱讀 39,711評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖窟勃,靈堂內(nèi)的尸體忽然破棺而出祖乳,到底是詐尸還是另有隱情,我是刑警寧澤秉氧,帶...
    沈念sama閱讀 35,424評論 5 343
  • 正文 年R本政府宣布眷昆,位于F島的核電站,受9級特大地震影響汁咏,放射性物質(zhì)發(fā)生泄漏亚斋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,017評論 3 326
  • 文/蒙蒙 一攘滩、第九天 我趴在偏房一處隱蔽的房頂上張望帅刊。 院中可真熱鬧,春花似錦漂问、人聲如沸赖瞒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栏饮。三九已至,卻和暖如春磷仰,著一層夾襖步出監(jiān)牢的瞬間袍嬉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評論 1 269
  • 我被黑心中介騙來泰國打工灶平, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伺通,地道東北人。 一個月前我還...
    沈念sama閱讀 47,722評論 2 368
  • 正文 我出身青樓民逼,卻偏偏與公主長得像泵殴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拼苍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,611評論 2 353

推薦閱讀更多精彩內(nèi)容