工廠模式(簡單工廠模式、工廠方法模式和抽象工廠模式)

參考文章:
漫畫:設(shè)計(jì)模式之 “工廠模式”
漫畫:什么是 “抽象工廠模式” 裤园?

自己簡單總結(jié)一下撤师,加強(qiáng)下記憶。

簡單工廠模式

就一個(gè)工廠類拧揽,里面通過if-else判斷邏輯來決定生產(chǎn)哪個(gè)產(chǎn)品剃盾。比如:

class SimpleFactory {
    
  public Product createdProduct(String type){
             if("1".equels(type)){
                //創(chuàng)建產(chǎn)品A
              } else if("2".equels(type)){
                //創(chuàng)建產(chǎn)品B
        }
  } 
}

簡單工廠可以滿足簡單業(yè)務(wù)場景下的需求,但是如果type類型很多淤袜,這里的if-else豈不是要一大堆痒谴。并且隨著業(yè)務(wù)的發(fā)展,type可以繼續(xù)增加铡羡,每次增加都需要修改工廠的判斷邏輯积蔚,不滿足開閉原則

工廠方法模式

上面簡單工廠的缺點(diǎn):不能適應(yīng)type的拓展烦周,不滿足開閉原則尽爆。

為了消除if-else,我們需要調(diào)用者自己決定生產(chǎn)哪些產(chǎn)品读慎。問題來了漱贱,如果讓調(diào)用方直接new 不同的產(chǎn)品,那還需要設(shè)計(jì)模式干嘛夭委。所以饱亿,這里我們讓調(diào)用者決定生產(chǎn)產(chǎn)品,不是直接new產(chǎn)品闰靴,而是直接調(diào)用產(chǎn)品工廠彪笼。

所以,我們可知工廠方法模式需要?jiǎng)?chuàng)建多個(gè)工廠類蚂且,來給調(diào)用方使用配猫。每個(gè)工廠類,只負(fù)責(zé)自己的產(chǎn)品生產(chǎn)杏死。這樣的話泵肄,調(diào)用方只需要new產(chǎn)品工廠即可。

服務(wù)端代碼如下:

public interface IMaskFactory {
    IMask createMask();
}

public class HighEndFactory implements IMaskFactory{

    @Override
    public IMask createMask() {
        IMask mask =  new HighEndMask();
        // .....
        // HighEndMask的100行初始化代碼
        return mask;
    }
}

public class LowEndFactory implements IMaskFactory{

    @Override
    public IMask createMask() {
        IMask mask =  new LowEndMask();
        // .....
        //  LowEndMask的100行初始化代碼
        return mask;
    }
}

客戶端代碼如下:

public class Test {

    public static void main(String[] args) {
        IMaskFactory factoryA = new LowEndFactory();
        IMaskFactory factoryB = new HighEndFactory();
        IMask maskA = factoryA.createMask();
        IMask maskB = factoryB.createMask();
        maskA.show();
        maskB.show();
    }
}

你可能會(huì)覺得new工廠類淑翼,和new 產(chǎn)品類腐巢,有啥不一樣⌒ǎ客戶端代碼冯丙,一行也沒少寫,想要修改客戶端需求遭京,還是得改客戶端代碼胃惜。
我們可以從另外一個(gè)角度看:new工廠類泞莉,不new 產(chǎn)品類,相當(dāng)于把產(chǎn)品和客戶端解耦了船殉,用工廠類這個(gè)中間人來黏和鲫趁。這樣的話,我們想改產(chǎn)品類利虫,只要改對應(yīng)的工廠類即可挨厚。達(dá)到解耦的效果,是不是有點(diǎn)spring ioc的味道了糠惫。

這種模式也有缺點(diǎn):每個(gè)產(chǎn)品都需要對應(yīng)一個(gè)工廠類疫剃,每增加一個(gè)產(chǎn)品,都必須相應(yīng)增加工廠類寞钥,導(dǎo)致類數(shù)量爆炸式增長慌申。

克服這種缺點(diǎn),我們就必須再抽象一個(gè)層次理郑。比如:提取各個(gè)產(chǎn)品的共性蹄溉,根據(jù)共性創(chuàng)建抽象工廠。

舉個(gè)例子:口罩和防護(hù)服兩個(gè)產(chǎn)品您炉,我們現(xiàn)在要添加一個(gè)高端和低端兩個(gè)質(zhì)量柒爵,用工廠方法的話,就需要 2 * 2 = 4個(gè)工廠類(高端口罩赚爵、低端口罩棉胀、高端防護(hù)服和低端防護(hù)服)。如果產(chǎn)品不止兩個(gè)呢冀膝,比如20個(gè)產(chǎn)品都需要高端和低端唁奢,那么工廠方法模板就需要40個(gè)工廠類。這種增加速度太快了窝剖,無法接受麻掸。

所以抽象工廠模式應(yīng)運(yùn)而生,對產(chǎn)品提取共性:高端和低端赐纱。那么就創(chuàng)建兩個(gè)抽象工廠類:高端工廠類和低端工廠類脊奋。這兩個(gè)抽象類,其實(shí)并不能生產(chǎn)具體產(chǎn)品疙描。只能知道诚隙,高端工廠類能生成高端的產(chǎn)品,至于產(chǎn)品是誰并不知道起胰。所以久又,這種方法簡單的解決方法就是通過抽象工廠類的方法來解決。

每個(gè)抽象類里面,有不同產(chǎn)品的創(chuàng)建方法籽孙。這些方法都只會(huì)創(chuàng)建高端產(chǎn)品或低端產(chǎn)品烈评。
如下:

public interface IFactory {
    //創(chuàng)建口罩
    IMask createMask();
    //創(chuàng)建防護(hù)服
    IProtectiveSuit createSuit();
}

public class LowEndFactory implements IFactory {
    @Override
    public IMask createMask() {
        IMask mask =  new LowEndMask();
        // .....
        //  LowEndMask的100行初始化代碼
        return mask;
    }

    @Override
    public IProtectiveSuit createSuit() {
        IProtectiveSuit suit =  new LowEndProtectiveSuit();
        // .....
        //  LowEndProtectiveSuit的100行初始化代碼
        return suit;
    }
}

public class HighEndFactory implements IFactory {
    @Override
    public IMask createMask() {
        IMask mask =  new HighEndMask();
        // .....
        // HighEndMask的100行初始化代碼
        return mask;
    }

    @Override
    public IProtectiveSuit createSuit() {
        IProtectiveSuit suit =  new HighEndProtectiveSuit();
        // .....
        //  HighEndProtectiveSuit的100行初始化代碼
        return suit;
    }
}

createMask和createSuit是創(chuàng)建產(chǎn)品的接口方法火俄,每個(gè)具體工廠類只會(huì)生產(chǎn)高端或低端產(chǎn)品犯建。
這樣的話,就只需要兩個(gè)工廠類瓜客,而非40個(gè)工廠類适瓦。

但是接口方法會(huì)有40個(gè)產(chǎn)品方法,這個(gè)是沒法省的谱仪。

但是它也有缺點(diǎn):
客戶端再使用的時(shí)候玻熙,只需要高端口罩。但是拿到的是高端工廠疯攒,可以生產(chǎn)所有高端產(chǎn)品包括:高端口罩嗦随,高端防護(hù)服和高端其他產(chǎn)品。這樣也很危險(xiǎn)敬尺,看到了不需要的功能枚尼,違背了最小原則

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末砂吞,一起剝皮案震驚了整個(gè)濱河市署恍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蜻直,老刑警劉巖盯质,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異概而,居然都是意外死亡呼巷,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進(jìn)店門赎瑰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來王悍,“玉大人,你說我怎么就攤上這事乡范∨涿” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵晋辆,是天一觀的道長渠脉。 經(jīng)常有香客問我,道長瓶佳,這世上最難降的妖魔是什么芋膘? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上为朋,老公的妹妹穿的比我還像新娘臂拓。我一直安慰自己,他們只是感情好习寸,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布胶惰。 她就那樣靜靜地躺著,像睡著了一般霞溪。 火紅的嫁衣襯著肌膚如雪孵滞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天鸯匹,我揣著相機(jī)與錄音坊饶,去河邊找鬼。 笑死殴蓬,一個(gè)胖子當(dāng)著我的面吹牛匿级,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播染厅,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼痘绎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了糟秘?” 一聲冷哼從身側(cè)響起简逮,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尿赚,沒想到半個(gè)月后散庶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡凌净,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年悲龟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冰寻。...
    茶點(diǎn)故事閱讀 40,680評論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡须教,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斩芭,到底是詐尸還是另有隱情轻腺,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布划乖,位于F島的核電站贬养,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏琴庵。R本人自食惡果不足惜误算,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一仰美、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧儿礼,春花似錦咖杂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至这橙,卻和暖如春奏窑,著一層夾襖步出監(jiān)牢的瞬間导披,已是汗流浹背屈扎。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留撩匕,地道東北人鹰晨。 一個(gè)月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像止毕,于是被迫代替她去往敵國和親模蜡。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評論 2 361