隱喻是一種明智的學(xué)習(xí)方法。世界上很多深?yuàn)W的理論都是用隱喻來(lái)理解消化的。這是今天早晨看代碼大全第一章的感觸。一.拋花引狼 用些生活常識(shí)理解一下工廠模式。那么學(xué)習(xí)工廠模式,就先來(lái)談?wù)劰S。什么是工廠呢?這個(gè)好像還不應(yīng)該由我來(lái)下定義。我們只需要想一想工廠是什么樣的。生活中有很多個(gè)工廠。服裝制造工廠,汽車(chē)制造工廠,等等。都是用來(lái)生產(chǎn)產(chǎn)品的。每個(gè)工廠都有自己的生產(chǎn)線,銷(xiāo)售處等等。下面結(jié)合著頭腦中工廠的概念,來(lái)認(rèn)識(shí)一下GoF設(shè)計(jì)模式中的工廠模式。工廠就用來(lái)生產(chǎn)產(chǎn)品的。在我們程序設(shè)計(jì)過(guò)程中,每一個(gè)對(duì)象的創(chuàng)建,就象是一個(gè)產(chǎn)品的誕生。創(chuàng)建一個(gè)對(duì)象,是為了提供給一個(gè)使用者使用的,就象生產(chǎn)一個(gè)產(chǎn)品是為了提供給一個(gè)消費(fèi)者使用一樣。我們無(wú)時(shí)無(wú)刻不在調(diào)用著new()方法,就象Car car = new Car();然后,一個(gè)Car的對(duì)象car產(chǎn)生了。這個(gè)過(guò)程中,我們調(diào)用了Car的構(gòu)造器來(lái)產(chǎn)生對(duì)象。這樣看來(lái),好像并不需要工廠模式來(lái)為我們做什么啊?我們?cè)龠M(jìn)一步分析一下。現(xiàn)實(shí)生活中要買(mǎi)車(chē),不會(huì)簡(jiǎn)簡(jiǎn)單單的new Car()這樣做。至少,我們要明確,買(mǎi)什么類(lèi)型的車(chē)啊?買(mǎi)哪個(gè)廠家制造的車(chē)啊?買(mǎi)什么價(jià)位的車(chē)啊?買(mǎi)什么顏色的車(chē)啊等等。也許這些,你也可以由Car的構(gòu)造器通過(guò)參數(shù)傳遞來(lái)實(shí)現(xiàn)。那么再比如,如果價(jià)位低于x就買(mǎi)A類(lèi)型的車(chē),如果價(jià)位高于x就買(mǎi)B類(lèi)型的車(chē)。這樣也許也可以由構(gòu)造器進(jìn)行一次邏輯判斷來(lái)實(shí)現(xiàn)......這樣,我們不難發(fā)現(xiàn),問(wèn)題越復(fù)雜的時(shí)候,我們的構(gòu)造器也會(huì)變得越來(lái)越復(fù)雜。這樣明顯違背了面向?qū)ο蟮姆庋b(Encapsulation)和分派(Delegation)。我們應(yīng)該將代碼分派成一段一段,將每一段再“封裝”起來(lái)。這樣,形成松藕合的狀態(tài),以后如果需要修改,只要更改每一段,而不會(huì)牽一動(dòng)百。那么,我們應(yīng)該怎么做呢?其實(shí)上面的例子已經(jīng)潛在的告訴我們?cè)撛趺醋隽恕N业脑瓌t始終是,面向?qū)ο螅磺袕默F(xiàn)實(shí)中的理論出發(fā),很多都符合生活常識(shí)。現(xiàn)實(shí)中一個(gè)Car是如何產(chǎn)生的呢?這是廢話(huà)!當(dāng)然是是由工廠制造出來(lái)的。如果只提到工廠,那么很顯然,這個(gè)名詞是抽象的。我們看不到到底是哪家工廠。這樣就出現(xiàn)了另一個(gè)概念---抽象工廠。我們先不去仔細(xì)的理解什么是抽象工廠。還是先研究從現(xiàn)實(shí)的角度去看,一個(gè)Car是如何被生產(chǎn)的。首先有一個(gè)具體的汽車(chē)制造工廠。這個(gè)汽車(chē)制造工廠具有一般工廠都具有的特性。特殊的,它是生產(chǎn)汽車(chē)的,也就是在它的內(nèi)部存在汽車(chē)的生產(chǎn)線。同時(shí),工廠里還置有汽車(chē)的銷(xiāo)售處。用來(lái)對(duì)工廠外的消費(fèi)者進(jìn)行交易的。這樣,就產(chǎn)生了幾個(gè)相應(yīng)的部門(mén)(模塊)。說(shuō)了半天的廢話(huà),讓我們先來(lái)看個(gè)例子。
如果還沒(méi)有理解為什么要這樣寫(xiě),而不是都封裝到Car的構(gòu)造器里,那就硬記下來(lái)吧。因?yàn)橐院箅S著項(xiàng)目的深入,對(duì)CarFactory的擴(kuò)張會(huì)越來(lái)越多。到時(shí)候就會(huì)體會(huì)到這樣寫(xiě)的好處了。因?yàn)榕家彩浅醮螌W(xué)習(xí)。^.^!所以,以后涉及到一個(gè)對(duì)象創(chuàng)建的時(shí)候,就要考慮一下,是否需要應(yīng)用一下工廠模式。特別是,對(duì)于某些類(lèi),類(lèi)的創(chuàng)建就是類(lèi)的主要功能。二.孔孟之道書(shū)接上文,言歸正傳上面所講的無(wú)非是一種方法。一種采用工廠的模式來(lái)生產(chǎn)產(chǎn)品的方法。我之所以要在這里強(qiáng)調(diào),因?yàn)椋覀円獙W(xué)習(xí)的是這種模式,而不要把模式固定在某些名詞上。有可能,工廠,也是一種產(chǎn)品。現(xiàn)在,拋開(kāi)現(xiàn)實(shí)中的理論(好多大白話(huà)),從程序設(shè)計(jì)的角度去想工廠模式。工廠模式是創(chuàng)建型模式里面主要的模式之一,它的思想是把類(lèi)創(chuàng)建的邏輯和過(guò)程封裝起來(lái),隔離客戶(hù)端。我們通常創(chuàng)建類(lèi)的實(shí)例都是直接調(diào)用其構(gòu)造方法,這是最常用的方法,但是當(dāng)類(lèi)的體系變得復(fù)雜,類(lèi)的創(chuàng)建邏輯變得復(fù)雜的時(shí)候就需要在客戶(hù)端使用大量的判斷代碼,而且使用這些類(lèi)越多,這樣的代碼會(huì)充斥到系統(tǒng)各個(gè)地方。所以把類(lèi)的創(chuàng)建過(guò)程獨(dú)立開(kāi)來(lái),用另外的一個(gè)類(lèi)來(lái)負(fù)責(zé),這就引入了工廠模式。根據(jù)這個(gè)工廠類(lèi)的復(fù)雜程度,又分為工廠方法和抽象工廠模式。工廠方法模式(Factory Mehod Pattern) 簡(jiǎn)單工廠模式,一個(gè)工廠生產(chǎn)多個(gè)產(chǎn)品;抽象工廠模式(Abstract Factory Pattern) 更復(fù)雜的工廠模式,產(chǎn)生多個(gè)工廠;網(wǎng)上看見(jiàn)有前輩把工廠模式分成三種,還有一個(gè)簡(jiǎn)單工廠模式。我感覺(jué),無(wú)所謂。如果讓我來(lái)寫(xiě),很有可能就是一種模式,我都叫它抽象工廠模式。只不過(guò)在遇到不同程度的問(wèn)題時(shí)。這種模式的使用形式有些變化而已。至少我現(xiàn)在是這樣理解的。那我就接合應(yīng)用來(lái)說(shuō)一下我理解的工廠模式。比如,我們要建立一個(gè)有XX效果的類(lèi)Something。這個(gè)XX效果會(huì)影響到Something的構(gòu)造過(guò)程。原則上講,XX并不屬于Something中的固有屬性,只能說(shuō)XX是Something的一種特殊屬性或者是一種特殊效果。我們用工廠模式來(lái)構(gòu)造一下。首先引入一個(gè)工廠接口,此接口定義了Something的創(chuàng)建方法(也可以不定義在這里,在子工廠中實(shí)現(xiàn))。為了生產(chǎn)XX的Something,特別為其實(shí)現(xiàn)一個(gè)特定的子工廠類(lèi)。這個(gè)子工廠是專(zhuān)門(mén)用來(lái)生產(chǎn)具有XX效果的Something的。(同樣,我們也可以再實(shí)現(xiàn)一個(gè)子工廠,專(zhuān)門(mén)用來(lái)生產(chǎn)具有YY效果的Something。)這樣就把不同效果的Something創(chuàng)建方法隔離開(kāi)來(lái)。每種效果和Something的構(gòu)造過(guò)程是封裝在一起。我們可以根據(jù)情況來(lái)實(shí)現(xiàn)不同效果下的Something。總之就是不能把創(chuàng)建邏輯放在使用的客戶(hù)端。就是把創(chuàng)建對(duì)象的邏輯過(guò)程和使用過(guò)程放在一起(也就是放在客戶(hù)端)。或者說(shuō),不要讓使用產(chǎn)品的人看見(jiàn)產(chǎn)品是如何產(chǎn)生的。使用者看見(jiàn)的應(yīng)該只是產(chǎn)品工廠和工廠出售產(chǎn)品的“受付”(銷(xiāo)售處)。使用者只要走到工廠的門(mén)口,而不要讓使用者走到生產(chǎn)線去買(mǎi)東西。為什么這樣做呢?想想現(xiàn)實(shí)中為什么這樣做呢?也許就會(huì)理解了。如果一堆人排著大隊(duì)在生產(chǎn)線旁買(mǎi)東西。生產(chǎn)出一個(gè)賣(mài)一個(gè)。不亂嗎?一,對(duì)于產(chǎn)品的生產(chǎn)方來(lái)說(shuō),這樣做太危險(xiǎn)了,很難預(yù)測(cè)消費(fèi)者會(huì)無(wú)意中對(duì)生產(chǎn)線造成多打的影響。而且不方便管理。二,對(duì)于使用者來(lái)說(shuō),也不方便購(gòu)買(mǎi)。用戶(hù)希望的就是看到一個(gè)銷(xiāo)售窗口,我告訴你買(mǎi)什么,你給我什么產(chǎn)品就夠了。沒(méi)必要看見(jiàn)產(chǎn)品是如何產(chǎn)生的。千萬(wàn)不要讓用戶(hù)到生產(chǎn)線去買(mǎi)東西!會(huì)很危險(xiǎn)。三.看圖識(shí)字就像小學(xué)生學(xué)東西一樣來(lái)理解抽象工廠。你只說(shuō)工廠,那給我的感覺(jué)就是抽象的。因?yàn)槲也⒉恢滥阏f(shuō)的到底是那家工廠,什么工廠等等。但是,我可以想像到在一個(gè)很大的地方,耳邊傳來(lái)轟轟的聲音,生產(chǎn)線在工作的情景.......這就是抽象的工廠。具體的來(lái)說(shuō),生活中有很多的工廠。比如服裝制造工廠,洗滌品制造工廠,汽車(chē)制造工廠...他們都是工廠。他們都有自己的產(chǎn)品。而且,單說(shuō)服裝制造工廠,就有很多家...服裝制造工廠的產(chǎn)品有衣服,褲子等。洗滌品制造工廠的產(chǎn)品有洗衣粉,香皂等。從廠家的角度來(lái)講,不同的廠家生產(chǎn)相同或不同的產(chǎn)品。從產(chǎn)品的角度來(lái)講,同樣的產(chǎn)品由一個(gè)廠家或者多個(gè)廠家來(lái)生產(chǎn)。這個(gè)結(jié)構(gòu)看起來(lái)很復(fù)雜。所以,我們必須要引入抽象的概念。當(dāng)一個(gè)問(wèn)題很難用具體的某個(gè)實(shí)例來(lái)描述的時(shí)候,我們不妨想想引入抽象。首先是抽象的工廠,具體什么樣的工廠有其子工廠去實(shí)現(xiàn)。再進(jìn)一步,也有抽象的產(chǎn)品,具體的產(chǎn)品由其子產(chǎn)品去實(shí)現(xiàn)。舉例來(lái)說(shuō)。電腦生產(chǎn)工廠。其子工廠會(huì)有聯(lián)想電腦生產(chǎn)工廠,IBM電腦生產(chǎn)工廠等等。而IBM電腦這個(gè)產(chǎn)品,可能也是抽象的。其子產(chǎn)品可以有IBM臺(tái)式機(jī),IBM筆記本電腦。如何具體的實(shí)現(xiàn)我們的抽象工廠,就要隨問(wèn)題的應(yīng)用而定。可能世界上只有一種筆記本,可能IBM還生產(chǎn)汽車(chē)。沒(méi)有固定的實(shí)例,只有固定的模式。比如:
由此可見(jiàn),工廠方法確實(shí)為系統(tǒng)結(jié)構(gòu)提供了非常靈活強(qiáng)大的動(dòng)態(tài)擴(kuò)展機(jī)制,只要我們更換一下具體的工廠方法,系統(tǒng)其他地方無(wú)需一點(diǎn)變換,就有可能將系統(tǒng)功能進(jìn)行改頭換面的變化。個(gè)人理解。隨時(shí)補(bǔ)充。
歡迎來(lái)訪!^.^! 本BLOG僅用于個(gè)人學(xué)習(xí)交流! 目的在于記錄個(gè)人成長(zhǎng). 所有文字均屬于個(gè)人理解. 如有錯(cuò)誤,望多多指教!不勝感激!
Copyright © 久城