[设计模式篇]工厂模式和抽象工厂模式
最近在看Head First的Design Pattern,想想去年候捷來(lái)學(xué)校給我們講Design Pattern,但當(dāng)時(shí)水平太弱根本聽(tīng)不懂,今年想趁機(jī)再好好學(xué)一波,候捷反而不來(lái)了,哎,人生就是這樣,有些機(jī)會(huì)真的搞不好只有一次了,所以還是要多多珍惜,不然... ... (再水下去估計(jì)沒(méi)人看了,廢話少說(shuō),這篇就當(dāng)一個(gè)開(kāi)篇之作吧,雖然已經(jīng)看了不少了。)
Head First這本書(shū)用了一個(gè)披薩店的例子,從簡(jiǎn)單工廠(嚴(yán)格來(lái)說(shuō)這不算一種Gof的設(shè)計(jì)模式,更像是一種編程習(xí)慣),到介紹工廠模式,再介紹到抽象工廠模式,最后予以總結(jié),個(gè)人認(rèn)為這種結(jié)合具體事例來(lái)說(shuō)事的學(xué)習(xí)方法是非常值得推崇的,這里先對(duì)這段過(guò)程簡(jiǎn)單描述一下:
1.假設(shè)我們開(kāi)了一個(gè)披薩店,我們會(huì)賣各種各樣的披薩,我們最開(kāi)始想到的方法可能就是創(chuàng)建一個(gè)基本的Pizza父類,然后通過(guò)繼承產(chǎn)生我們披薩店賣的各種各樣的披薩子類,比如CheesePizza,GreekPizza... ...那么我們?cè)跊Q定生產(chǎn)一個(gè)披薩(調(diào)用orderPizza)時(shí),我們首先想到的方法是把披薩的類型當(dāng)作一個(gè)參數(shù)傳給orderPizza,然后寫(xiě)一堆的if else,比如
if (type.equals("Cheese")
//新建一個(gè)CheesePizza
else if....(我盡量少些代碼,因?yàn)槎急容^好理解)
這就是一個(gè)最基本的實(shí)現(xiàn),但隨著pizza類型的增多,我們改起來(lái)的壓力也越來(lái)越大,需要不停的使用 if else顯然不是一種最佳實(shí)踐,這是我們就引入“工廠”的概念了;
2.所謂“工廠”,就是為處理創(chuàng)建對(duì)象的細(xì)節(jié)建立的,這里我們的Pizza就可以看作是一個(gè)工廠,我們知道它生產(chǎn)Pizza(可能Pizza和披薩混用,大家理解就好),對(duì)于上面的情況,我們可以創(chuàng)建一個(gè)SimplePizzaFactory(也就是“簡(jiǎn)單披薩工廠”)將我們需要實(shí)例化的Pizza對(duì)象扔進(jìn)去,也就是將那一堆if else放到這里來(lái)實(shí)現(xiàn),也就是將創(chuàng)建披薩的代碼包裝進(jìn)一個(gè)類,以后實(shí)現(xiàn)改變時(shí),只需要修改這個(gè)類即可,ok,這就是簡(jiǎn)單工廠的思維。。。。有木有太簡(jiǎn)單了一點(diǎn),這么簡(jiǎn)單的想法怎么能算一種高大上的Design Pattern呢?所以它真的不算設(shè)計(jì)模式的一種,但這種將變化的部分抽取出來(lái)的思維個(gè)人感覺(jué)是很有必要掌握的,然后繼續(xù)我們的故事;
3.隨著你披薩店的發(fā)展,現(xiàn)在出現(xiàn)了不同地方的店像要加盟,比如有上海的,有北京的,有深圳的,不同的店制作的披薩不同,假設(shè)上海披薩薄,多汁啥的,北京披薩厚,芝士放得多... ...(就知道它們有區(qū)別就行了),這個(gè)時(shí)候?yàn)榱藵M足不同地方的需求,我們需要分別為這三個(gè)地方創(chuàng)建不同的披薩店(披薩工廠),分別是ShanghaiPizzaStore,BeijingPizzaStore,ShenZhenPizzaStore,對(duì)應(yīng)不同的披薩店生產(chǎn)不同的披薩(具體的實(shí)現(xiàn)細(xì)節(jié)先不管),在具體的調(diào)用中,我們先創(chuàng)建一個(gè)具體的披薩店,然后通過(guò)這個(gè)披薩店傳入的參數(shù)(比如cheese)來(lái)實(shí)例化一個(gè)披薩,這個(gè)過(guò)程用以下兩行代碼:
PizzaStror shStore = new ShanghaiPizzaStore();
Pizza pizza = shStore.orderPizza("cheese");
這樣就實(shí)例化了一個(gè)上海披薩店的起司披薩對(duì)象,這很簡(jiǎn)單,但客官您看好了,這里就引入了設(shè)計(jì)模式的概念了,對(duì)于一個(gè)工廠方法來(lái)說(shuō),我們有兩個(gè)平行的類層級(jí)--產(chǎn)品類和創(chuàng)建者類,這里的產(chǎn)品類就是我們的Pizza,創(chuàng)建者類就是我們的PizzaStore,工廠方法模式“定義了一個(gè)創(chuàng)建對(duì)象的接口,但由子類決定要實(shí)例化的類是那一個(gè)。工廠方法讓類把實(shí)例化推遲到了子類(Define an interface for creating a?single?object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses?)”,它幫助我們將產(chǎn)品的“實(shí)現(xiàn)”從“使用”中解耦,也就是說(shuō),當(dāng)我們的產(chǎn)品類受到影響時(shí)(披薩種類的增加啥的),我們的創(chuàng)建者PizzaStore并不會(huì)受到什么影響,它只負(fù)責(zé)去這個(gè)Pizza工廠中取具體的Pizza,這就時(shí)工廠方法模式的基本應(yīng)用了。(更深入的了解可以去查一查“Dependency Inversion Principle”,大名鼎鼎的“依賴倒置原則”,我也理解得不是很深,暫且按下不表);
4.好了,我們的工廠(產(chǎn)品)類有了,創(chuàng)建者也有了,那抽象工廠又是個(gè)什么東東呢?我們回到pizza店,考慮這樣一種情況,北京的披薩店和上海的披薩店,它們不但生產(chǎn)的披薩種類不同,這些披薩的原料也不同,也就是實(shí)例化一個(gè)披薩時(shí),我們要根據(jù)其地域來(lái)對(duì)它的面團(tuán),醬料啊具體分析,這個(gè)時(shí)候怎么辦呢?我們這是可以通過(guò)定義一個(gè)原料工廠的接口,然后在各地域的披薩店里實(shí)現(xiàn)這個(gè)接口,比如有上海披薩原料工廠,北京披薩原料工廠... ...這樣當(dāng)我們知道我們的披薩店之后,就可以實(shí)例化一個(gè)具體的原料工廠,這樣就可以提取原料來(lái)制作對(duì)應(yīng)的披薩了!沒(méi)錯(cuò),這就是抽象工廠的思想--"提供一個(gè)接口,用于創(chuàng)建相關(guān)或依賴對(duì)象的家族,而不需要明確指定具體類";這里的原料就是一個(gè)接口,當(dāng)我們的創(chuàng)建者確定之后,這個(gè)對(duì)應(yīng)的接口也就被對(duì)應(yīng)地實(shí)現(xiàn)了,這樣創(chuàng)建者就可以從這個(gè)工廠中去取我們的披薩原料了,通過(guò)這樣的組合來(lái)完成披薩的制作。
。。。。已經(jīng)快兩點(diǎn)了,明早還有課,介紹就到這里,其實(shí)Head First也差不多在這里結(jié)束了這張,具體工廠方法模式和抽象工廠的應(yīng)用,讀者可以去參考更多例子。因?yàn)槲乙彩浅鯇W(xué)者,理解肯定不全,我這樣記錄下來(lái)更多是希望大家一起來(lái)探索,于反復(fù)交流中探取真知,學(xué)習(xí)不就是這樣么?好了,不廢話了,歡迎交流,第一篇先到這里。
轉(zhuǎn)載于:https://www.cnblogs.com/krischan/p/5406606.html
總結(jié)
以上是生活随笔為你收集整理的[设计模式篇]工厂模式和抽象工厂模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。