設(shè)計(jì)模式干貨系列:(二)工廠方法模式【學(xué)習(xí)難度:★★☆☆☆奈偏,使用頻率:★★★★★】

前言

上一篇介紹簡單工廠模式的時候提到它對開閉原則支持的不夠坞嘀,因?yàn)槿绻行碌漠a(chǎn)品加入到系統(tǒng)中去,就需要修改工廠類惊来,就違反了開閉原則了丽涩,這次介紹的工廠方法模式在保持簡單工廠模式優(yōu)點(diǎn)的前提下,還滿足了開閉原則裁蚁,關(guān)鍵在于它的多態(tài)性矢渊。

正文

工廠方法模式概念

工廠方法模式是類的創(chuàng)建模式,又叫做虛擬構(gòu)造子(Cirtual Constructor)模式或者多態(tài)工廠(Polymorphic Factory)模式枉证。

工廠方法模式的用意是定義一個創(chuàng)建產(chǎn)品對象的工廠接口矮男,將實(shí)際創(chuàng)建工作推遲到子類中。

首先室谚,在工廠方法模式中毡鉴,核心的工廠類不再負(fù)責(zé)所有產(chǎn)品的創(chuàng)建,而是將具體創(chuàng)建的工作交給子類去做.這個核心類則搖身一變秒赤,成為了一個抽象工廠角色猪瞬,僅負(fù)責(zé)給出具體工廠子類必須實(shí)現(xiàn)的接口,而不接觸哪一個產(chǎn)品類應(yīng)當(dāng)被實(shí)例化這種細(xì)節(jié)入篮。

這種進(jìn)一步抽象化的結(jié)果陈瘦,使這種工廠方法模式可以用來予許系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品,也就遵循了開閉原則崎弃。

工廠方法模式的結(jié)構(gòu)

工廠方法模式的結(jié)構(gòu)圖如下:

從上圖可以看出甘晤, 工廠方法模式涉及到抽象工廠角色,具體工廠角色饲做,抽象產(chǎn)品角色以及具體產(chǎn)品角色等四個角色:

  • 抽象工廠角色:擔(dān)任這個角色的是工廠方法模式的核心线婚,它是與應(yīng)用程序無關(guān)的。任何在模式中創(chuàng)建對象的工廠類必須實(shí)現(xiàn)這個接口盆均。
  • 具體工廠角色:擔(dān)任這個角色的是實(shí)現(xiàn)了抽象工廠接口的具體Java類塞弊,具體工廠角色含有與應(yīng)用密切相關(guān)的邏輯,并且受到應(yīng)用程序的調(diào)用以創(chuàng)建產(chǎn)品對象泪姨。
  • 抽象產(chǎn)品角色:工廠方法模式所創(chuàng)建的對象的超類型游沿,也就是產(chǎn)品對象的共同父類或共同擁有的接口桥狡。
  • 具體產(chǎn)品角色:這個角色實(shí)現(xiàn)了抽象產(chǎn)品角色所申明的接口卦绣。工廠方法模式所創(chuàng)建的每一個對象都是某個具體產(chǎn)品角色的實(shí)例。

結(jié)合披薩系統(tǒng)咙崎,用白話文來說就是之前廚師(工廠類)負(fù)責(zé)所有的烤披薩任務(wù)仗处,太累了眯勾。于是招了兩個廚師分別負(fù)責(zé)烤 GreekPizza披薩和 CheesePizza披薩,之前的廚師升級為廚師長(抽象工廠類)婆誓,負(fù)責(zé)教那兩位廚師(具體工廠類)烤披薩吃环,自己則不用親自動手烤披薩了。

附上代碼前先來看看完整的類圖:

代碼示例講解

下面是抽象產(chǎn)品的角色Pizza的源代碼:

public abstract class Pizza {
    public abstract void prepare();
    public abstract void bake();
    public abstract void cut();
    public abstract void box();
}

下面是具體產(chǎn)品角色CheesePizza的源代碼:

public class CheesePizza extends Pizza{
    public void prepare(){
        System.out.println("準(zhǔn)備CheesePizza~");
    }
    public void bake(){
        System.out.println("正在烤CheesePizza~");
    }
    public void cut(){
        System.out.println("正在切CheesePizza~");
    }
    public void box(){
        System.out.println("正在打包CheesePizza~");
    }
}

下面是具體產(chǎn)品角色GreekPizza的源代碼:

public class GreekPizza  extends Pizza{
    public void prepare(){
        System.out.println("準(zhǔn)備GreekPizza~");
    }
    public void bake(){
        System.out.println("正在烤GreekPizza~");
    }
    public void cut(){
        System.out.println("正在切GreekPizza~");
    }
    public void box(){
        System.out.println("正在打包GreekPizza~");
    }
}

下面是抽象工廠角色PizzaFactory的代碼,這個角色是使用一個java接口實(shí)現(xiàn)洋幻,它聲明了一個工廠方法郁轻,要求所有的具體工廠角色實(shí)現(xiàn)這個工廠方法:

 public interface PizzaFactory {
    /**
     * 工廠方法
     * @return
     */
    public Pizza createPizza();
}

下面是具體工廠角色CheesePizzaFactory的代碼,這個角色現(xiàn)實(shí)了抽象工廠角色PizzaFactory所聲明的工廠方法:

 public class CheesePizzaFactory implements PizzaFactory{
    @Override
    public Pizza createPizza() {
        return new CheesePizza();
    }
}

下面是具體工廠角色GreekPizzaFactory的代碼文留,這個角色現(xiàn)實(shí)了抽象工廠角色PizzaFactory所聲明的工廠方法:

public class GreekPizzaFactory  implements PizzaFactory{
    @Override
    public Pizza createPizza() {
        return new GreekPizza();
    }
}

下面是客戶端角色的源代碼:

public class OrderPizza {
    public static void main(String[] args){
        PizzaFactory factory=new CheesePizzaFactory();
        Pizza pizza=factory.createPizza();
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        factory=new GreekPizzaFactory();
        pizza=factory.createPizza();
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
    }
}

結(jié)果演示:

準(zhǔn)備CheesePizza~
正在烤CheesePizza~
正在切CheesePizza~
正在打包CheesePizza~
準(zhǔn)備GreekPizza~
正在烤GreekPizza~
正在切GreekPizza~
正在打包GreekPizza~

這里使用工廠方法模式的注意點(diǎn):
** 工廠方法創(chuàng)建對象**:
工廠方法不一定每一次都返還一個新的對象好唯,但是它所返還的對象一定是它自己創(chuàng)建的。

工廠方法返還的類型
注意:工廠方法返還的應(yīng)當(dāng)是抽象類型厂庇,而不是具體類型渠啊,只有這樣才能保證針對產(chǎn)品的多態(tài)性。當(dāng)工廠方法模式發(fā)生上面的退化時权旷,就不再是工廠方法模式了替蛉。

工廠等級結(jié)構(gòu)
工廠對象應(yīng)當(dāng)有一個抽象的超類型。換言之拄氯,應(yīng)當(dāng)有數(shù)個具體工廠類作為一個抽象超類型的具體子類存在于工廠等級結(jié)構(gòu)中躲查。如果等級結(jié)構(gòu)中只有一個具體工程類的話,那么抽象工廠角色也可以省略译柏,這時候镣煮,工廠方法模式就發(fā)生了退化,這一退化表現(xiàn)為針對工廠角色的多態(tài)性的喪失鄙麦。

總結(jié)

工廠方法模式和簡單工廠模式比較
工廠方法模式跟簡單工廠模式在結(jié)構(gòu)上的不同是很明顯的典唇,工廠方法模式的核心是一個抽象工廠類镊折,而簡單工廠模式的核心在一個具體類。顯而易見工廠方法模式這種結(jié)構(gòu)更好擴(kuò)展介衔,權(quán)力下發(fā)恨胚,分布式比集中式更具優(yōu)勢。

如果系統(tǒng)需要加入一個新的產(chǎn)品炎咖,那么所需要的就是向系統(tǒng)中加入一個這個產(chǎn)品類以及它所對應(yīng)的工廠類赃泡。沒有必要修改客戶端,也沒有必要修改抽象工廠角色或者其他已有的具體工廠角色乘盼。對于增加新的產(chǎn)品類而言升熊,這個系統(tǒng)完全支持開閉原則。


源碼放百度網(wǎng)盤绸栅,有需要自己取级野,對應(yīng)目錄如下
simplefactory:簡單工廠模式
methodFactory:工廠方法模式
AbstractFactory:抽象工廠模式
鏈接:http://pan.baidu.com/s/1kUNygBl
密碼:vc9f


一直覺得自己寫的不是技術(shù),而是情懷粹胯,一篇篇文章是自己這一路走來的痕跡勺阐。靠專業(yè)技能的成功是最具可復(fù)制性的矛双,希望我的這條路能讓你少走彎路渊抽,希望我能幫你抹去知識的蒙塵,希望我能幫你理清知識的脈絡(luò)议忽,希望未來技術(shù)之巔上有你也有我懒闷。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市栈幸,隨后出現(xiàn)的幾起案子愤估,更是在濱河造成了極大的恐慌,老刑警劉巖速址,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玩焰,死亡現(xiàn)場離奇詭異,居然都是意外死亡芍锚,警方通過查閱死者的電腦和手機(jī)昔园,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來并炮,“玉大人默刚,你說我怎么就攤上這事√悠牵” “怎么了荤西?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我邪锌,道長勉躺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任觅丰,我火速辦了婚禮赂蕴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘舶胀。我一直安慰自己,他們只是感情好碧注,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布嚣伐。 她就那樣靜靜地躺著,像睡著了一般萍丐。 火紅的嫁衣襯著肌膚如雪轩端。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天逝变,我揣著相機(jī)與錄音基茵,去河邊找鬼。 笑死壳影,一個胖子當(dāng)著我的面吹牛拱层,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宴咧,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼根灯,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掺栅?” 一聲冷哼從身側(cè)響起烙肺,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎氧卧,沒想到半個月后桃笙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡沙绝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年搏明,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闪檬。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡熏瞄,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谬以,到底是詐尸還是另有隱情强饮,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布为黎,位于F島的核電站邮丰,受9級特大地震影響行您,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剪廉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一娃循、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧斗蒋,春花似錦捌斧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至跷究,卻和暖如春姓迅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背俊马。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工丁存, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柴我。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓解寝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親艘儒。 傳聞我的和親對象是個殘疾皇子编丘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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