一、工廠模式定義:
根據(jù)給出的信息創(chuàng)建特定類的實例卿拴,以達(dá)到程序解耦的目的衫仑。
二、使用場景目的:
一般用在創(chuàng)建對象的情況比較復(fù)雜堕花,在整個程序的開發(fā)及運維階段文狱,無法預(yù)知將要
創(chuàng)建哪些類的實例。將直接創(chuàng)建對象的方式改為從工廠中獲取缘挽,達(dá)到解耦的目的瞄崇。
舉個例子:在人類文明尚且處于蒙昧的階段,我們需要某種水果時壕曼,唯一的辦法也
許就是自己去摘取苏研,需要其它某些食物時,也同樣如此腮郊,這樣嚴(yán)重阻礙了生產(chǎn)力的
發(fā)展摹蘑。隨著社會的進(jìn)步,出現(xiàn)了交換行為轧飞,進(jìn)而出現(xiàn)了社會分工衅鹿。有專門負(fù)責(zé)種植
水果的人,專門負(fù)責(zé)販賣水果的人(單一職責(zé)原則)过咬。這樣尚嫌不夠大渤,我們想吃葡
萄的時候,不一定非要去找專門販賣葡萄的商販掸绞,通常一個水果商會販賣多種水
果泵三,我們僅需要告訴他我們想要什么類型的水果,然后由他向我們提供即可集漾,至于
每一種水果是怎么來的切黔,則與我們無關(guān)。我們不需要關(guān)心水果是產(chǎn)自哪棵果樹具篇、以
及這顆果樹是怎么管理的纬霞。這就是工廠模式的思想。這是政治經(jīng)濟學(xué)的一個例子驱显,
不屬于本章的范疇诗芜,但它很能說明編程中的問題瞳抓。如果想要更深入的了解,請參看
亞當(dāng)斯密的《國富論》第一卷:論分工伏恐。之所以舉這個例子是為了說明:政治經(jīng)濟
學(xué)的方法論是哲學(xué)的孩哑,計算機科學(xué)的方法論也同樣是哲學(xué)的。我們不應(yīng)該執(zhí)著于具
體的實現(xiàn)翠桦,而應(yīng)該具備某些思想横蜒,這些思想是解決問題的源泉。
三销凑、工廠模式分類:
1丛晌、簡單工廠模式:
簡單工廠模式實現(xiàn)起來尤為簡單,以至于很多人不把它歸納到工廠模式中來斗幼。但
它確是工廠模式的一種澎蛛。例如幾何學(xué)中對于鈍角的定義如下:“大于直角的角叫做
鈍角”,那么只要符合這個定義的我們都可以稱之為鈍角蜕窿。簡單工廠模式也一樣谋逻,
不能因為它過于簡單,而排除在工廠模式之外桐经。同樣的毁兆,我們也可以使用其它方
法實現(xiàn)工廠模式,只要它能夠達(dá)到解耦的目的次询,我認(rèn)為這些都是可行的荧恍。我會牢
記一個原則:能夠最簡單、最直接的達(dá)到目的的時候屯吊,我不會去走任何曲折的道
路送巡。
代碼:
該接口提供了一個抽象的水果品類,用于實現(xiàn)多態(tài)盒卸。
以上三個具體的蘋果骗爆、香蕉、桃子實現(xiàn)了水果接口蔽介,也就是說摘投,它們都是水果,具有同一個類型虹蓄。
在水果工廠中使用了一個枚舉類犀呼,用于定義水果的類型。還有一個購買水果的方法薇组,傳入相應(yīng)的水果類型信息外臂,獲取特定水果的實例。
至此一個簡單工廠模式就實現(xiàn)了律胀,我認(rèn)為情況不是特別復(fù)雜的情況下宋光,使用這種方式就很大程度上做到了代碼的解耦貌矿。當(dāng)然這種方式也是有它的缺點的:如果我們要水果工廠再多生產(chǎn)幾種水果,那么不可避免的需要添加枚舉類型罪佳、需要在購買水果方法中多幾個case語句逛漫。這樣的做法顯然違背了開閉原則,也不夠優(yōu)雅赘艳。但是使用反射的方式呢酌毡?
下面我們改造一下FruitFactory類:
現(xiàn)在工廠類只存在一個購買水果的方法,并且它的入?yún)l(fā)生了變化:它不再需要一個水果的枚舉類型蕾管,而是需要傳入一個實現(xiàn)了水果接口的任意類型的class對象±觯現(xiàn)在這個工廠已經(jīng)具備了一種動態(tài)擴展的性質(zhì),如果我們需要添加新的水果娇掏,僅僅讓這個新的水果類實現(xiàn)水果接口即可,無須增加或修改任何代碼勋眯,已經(jīng)可以從工廠類中獲取任意水果類型的實例了婴梧。我個人認(rèn)為這是簡單工廠模式完美的實現(xiàn),雖然這個工廠類僅僅使用了幾行代碼客蹋。但是我們想想之前的那個原則(如果認(rèn)同的話):能夠使用最直接塞蹭、最簡單的方式達(dá)到目的,絕不采用任何曲折繁雜的方式去實現(xiàn)讶坯。當(dāng)然番电,這種實現(xiàn)方式也并非無可挑剔,比如:如果構(gòu)造實例時需要初始化參數(shù)辆琅、構(gòu)造器私有等等漱办。但這是工廠模式都能夠遇到的問題,使用這種方式也是可以進(jìn)行解決的婉烟。spring中就大量使用了反射來創(chuàng)建對象娩井,我認(rèn)為這種方式之所以沒有被人提及,不過是因為過于簡單罷了似袁。
2洞辣、工廠方法模式
定義一個水果工廠接口,里面僅有購買水果這一抽象行為昙衅,至于買什么水果扬霜,要在具體工廠里面去實現(xiàn)。
新建兩個具體的水果工廠類而涉,都實現(xiàn)水果工廠接口著瓶。
這種模式解決了需要創(chuàng)建對象種類非常多、且創(chuàng)建對象方式復(fù)雜的情況下婴谱,頻繁修改購買水果接口蟹但,增加購買水果方法的復(fù)雜度躯泰。很大程度上遵守了開閉原則。但是很顯然华糖,這種方式不過是把方法的復(fù)雜度轉(zhuǎn)移到了類級別上麦向,如果項目復(fù)雜程度較高時,這種方式無疑是一種比較好的選擇客叉。這種方式的缺點也是很明顯的:針對每一個具體產(chǎn)品創(chuàng)建一個工廠類诵竭,成本是不是太高了?
3兼搏、抽象工廠模式:
接下來我們想象會遇到這樣一種場景:我們購買各種水果來制作不同的水果蛋糕÷盐浚現(xiàn)
在僅僅是購買水果還是不夠的,我們還需要購買奶油及其它材料佛呻,現(xiàn)在修改一下代
碼:
定義一個抽象接口裳朋,并提供一個獲取奶油種類名稱的方法。
定義一個動物淡奶油類吓著,然后蛋糕制作商為了節(jié)約成本鲤嫡,還會選擇人造奶油作為原料。現(xiàn)在這兩種材料都實現(xiàn)了奶油接口绑莺,因此是無差別的暖眼。這兩種材料制作的蛋糕都叫做奶油蛋糕。
定義一個抽象工廠類纺裁。
一個具體的水果工廠诫肠,繼承了抽象工廠,并提供根據(jù)傳入的class對象欺缘,動態(tài)獲取水果的方法栋豫。
具體的奶油工廠,實現(xiàn)了獲取奶油的抽象方法浪南。
創(chuàng)建一個工廠建造者類笼才,根據(jù)傳入的class對象,動態(tài)獲取工廠實例络凿。獲取工廠實例的方法仍然使用反射動態(tài)獲取骡送。
測試類中,根據(jù)特定工廠類的class對象絮记,獲取相應(yīng)的工廠對象摔踱,并且根據(jù)具體的水果及奶油類型,獲取到了具體的水果怨愤,最后制作成了廉價的“蘋果人造奶油蛋糕”派敷。
結(jié)論:
抽象工廠模式用于解決多個不同的類實例的創(chuàng)建,其可擴展性要優(yōu)于簡單工廠模式
及工廠方法模式。但就其實現(xiàn)方式來說篮愉,也比其他工廠模式要更加復(fù)雜腐芍。而且需要
針對每一個類創(chuàng)建一個工廠實現(xiàn)類,并在抽象工廠中加入獲取具體工廠的方法试躏。工
廠模式充分利用了java多態(tài)的特性猪勇,是利用多態(tài)進(jìn)行解耦的一個比較好的實現(xiàn),也
是依賴倒置原則的一種體現(xiàn)颠蕴。但在使用時應(yīng)該根據(jù)具體情況來判斷使用哪一種模式
更好泣刹,畢竟不能像本章的demo一樣,為了“輸出一句hello word”而實現(xiàn)一個抽象工
廠模式犀被。本章的demo僅僅是一個例子椅您,用來說明工廠模式的具體實現(xiàn)。