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