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