設(shè)計(jì)模式學(xué)習(xí)總結(jié)_第1頁(yè)
設(shè)計(jì)模式學(xué)習(xí)總結(jié)_第2頁(yè)
設(shè)計(jì)模式學(xué)習(xí)總結(jié)_第3頁(yè)
設(shè)計(jì)模式學(xué)習(xí)總結(jié)_第4頁(yè)
設(shè)計(jì)模式學(xué)習(xí)總結(jié)_第5頁(yè)
已閱讀5頁(yè),還剩6頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

..設(shè)計(jì)模式學(xué)習(xí)總結(jié)引子剛開場(chǎng)學(xué)習(xí)設(shè)計(jì)模式的時(shí)候,感到這些模式真的非常抽象。今年下半年以來(lái),隨著我們組工作重點(diǎn)的轉(zhuǎn)移,以及我在小組中角色的變化,我開場(chǎng)有條件提出自己對(duì)新系統(tǒng)的設(shè)計(jì)想法。在設(shè)計(jì)過程中,我發(fā)現(xiàn)了很多設(shè)計(jì)模式的用處,也確實(shí)應(yīng)用了很多設(shè)計(jì)模式,這讓我越來(lái)越感到設(shè)計(jì)模式的重要性,因此我寫了這十余篇專門介紹設(shè)計(jì)模式的文章,作為我的學(xué)習(xí)筆記。"設(shè)計(jì)模式——可復(fù)用的面向?qū)ο筌浖母?〔有趣的是,梅宏一再在組會(huì)上強(qiáng)調(diào)應(yīng)該譯成重用〕中介紹了一共23種設(shè)計(jì)模式,我一共寫了19個(gè)設(shè)計(jì)模式〔其中三個(gè)和在一篇文章中〕,余下四個(gè),考慮到該模式的應(yīng)用圍我就沒有介紹。在寫這些文章時(shí),其中的很多例子都是我在實(shí)踐中提煉出來(lái)的,當(dāng)然也有很大一局部是"設(shè)計(jì)模式"中的例子。不過,這四個(gè)人〔四人團(tuán)〕生活的年代里現(xiàn)在已經(jīng)很遠(yuǎn)了,所以它們的例子也很古老。讓我們更加設(shè)計(jì)模式設(shè)計(jì)模式是個(gè)好東西,它給出了很多設(shè)計(jì)中的技巧與思路,對(duì)于很多優(yōu)秀的設(shè)計(jì),它加以總結(jié)與提煉。設(shè)計(jì)模式并非四人團(tuán)拍腦瓜想出來(lái)的,而是他們搜集了其他人優(yōu)秀的設(shè)計(jì),加以整理出來(lái)的,他們不是這些模式的創(chuàng)造者,僅僅是整理者。應(yīng)用設(shè)計(jì)模式會(huì)給我們帶來(lái)很多好處:軟件將變得更加靈活,模塊之間的耦合度將會(huì)降低,效率會(huì)提升,開銷會(huì)減少。更重要的,設(shè)計(jì)模式就好似美聲唱法中的花腔,讓你的設(shè)計(jì)更加漂亮??偟膩?lái)說,設(shè)計(jì)模式似乎將軟件設(shè)計(jì)提升到藝術(shù)的層次。設(shè)計(jì)模式已經(jīng)被廣泛的應(yīng)用了,在現(xiàn)在很多的圖形界面框架都使用了MVC模式,大量跌代器模式的應(yīng)用,徹底改變了我們對(duì)集合的操作方式。不僅如此,應(yīng)用了設(shè)計(jì)模式的設(shè)計(jì),往往被看成為優(yōu)秀的設(shè)計(jì)。這是因?yàn)?,這些設(shè)計(jì)模式都是久經(jīng)考驗(yàn)的。模式不是模型在學(xué)習(xí)和使用設(shè)計(jì)模式的時(shí)候,往往出現(xiàn)一個(gè)非常嚴(yán)重的誤區(qū),那就是設(shè)計(jì)模式必須嚴(yán)格地遵守,不能修改。但是設(shè)計(jì)模式不是設(shè)計(jì)模型,并非一成不變。正相反,設(shè)計(jì)模式中最核心的要素并非設(shè)計(jì)的構(gòu)造,而是設(shè)計(jì)的思想。只有掌握住設(shè)計(jì)模式的核心思想,才能正確、靈活的應(yīng)用設(shè)計(jì)模式,否那么再怎么使用設(shè)計(jì)模式,也不過是生搬硬套。當(dāng)然,掌握設(shè)計(jì)模式的思想,關(guān)鍵是要仔細(xì)研究模式的意圖和構(gòu)造。一個(gè)模式的意圖,就是使用這個(gè)設(shè)計(jì)模式的目的,表達(dá)了為什么要使用這個(gè)模式,也就是需求問題。這個(gè)模式的構(gòu)造,就是如何去解決這個(gè)問題,是一種手段、一種經(jīng)典的解決方法,這種解決方法只是一種建議。兩個(gè)方面結(jié)合起來(lái),明白為什么需要設(shè)計(jì)模式,同時(shí)明白了如何實(shí)現(xiàn)這個(gè)模式,就容易抓住模式的本質(zhì)思想。在抓住意圖和構(gòu)造的根底上,實(shí)踐也是掌握設(shè)計(jì)模式的必要方法。當(dāng)然,設(shè)計(jì)模式必須在某個(gè)場(chǎng)景下得到應(yīng)用才有意義,這也是為什么"設(shè)計(jì)模式"中提供了大量的例子用來(lái)說明模式的應(yīng)用場(chǎng)景,這實(shí)際上為讀者提供了一種上下文環(huán)境。學(xué)外語(yǔ)不是要強(qiáng)調(diào)"語(yǔ)言環(huán)境〞么,學(xué)習(xí)設(shè)計(jì)模式也是這樣。不要設(shè)計(jì)模式看到網(wǎng)上很多人在討論設(shè)計(jì)模式,他們確實(shí)很有***,滿嘴都是模式的名字,恨不得寫個(gè)HelloWorld都要應(yīng)用到設(shè)計(jì)模式。設(shè)計(jì)模式確實(shí)是好東西,但是,中國(guó)有句古話叫作物極必反,即便是按照辯證法,事物總要一分為二的看。我們說設(shè)計(jì)模式的目的是為了讓軟件更加靈活,重用度更高。但是,某種意義上,設(shè)計(jì)模式增加了軟件維護(hù)的難度,特別是它增加了對(duì)象之間關(guān)聯(lián)的復(fù)雜度。我們總說,重用可以提高軟件開發(fā)的效率。如果你是大牛,你自然希望你的設(shè)計(jì)可以被反復(fù)使用10000年,那就是:當(dāng)世界消滅的時(shí)候,你的設(shè)計(jì)依然存在。然而,現(xiàn)實(shí)是一個(gè)系統(tǒng)的設(shè)計(jì)往往在5年之就會(huì)被拋棄,這是因?yàn)椋?,軟件技術(shù)產(chǎn)生了新的變化,使用新的技術(shù)進(jìn)展的設(shè)計(jì),無(wú)論如何都比你的設(shè)計(jì)好;2,硬件環(huán)境發(fā)生了很大變化,你的設(shè)計(jì)里對(duì)開銷或者效率的追求已經(jīng)沒有意義了;3,新的大牛出現(xiàn)了,并且取代了你的位置。應(yīng)用設(shè)計(jì)模式會(huì)導(dǎo)致設(shè)計(jì)周期的加長(zhǎng)〔因?yàn)楦鼜?fù)雜了〕,但是很多工程還在設(shè)計(jì)階段就已經(jīng)胎死腹中,再好的設(shè)計(jì)也沒有發(fā)揮的余地。當(dāng)我們向設(shè)計(jì)模式頂禮膜拜的時(shí)候,我們還必須清醒地看到軟件生產(chǎn)中非技術(shù)層面上的東西往往具有決定性作用。理想固然崇高,但現(xiàn)實(shí)總是殘酷的。如何看清理想與現(xiàn)實(shí)的界限,恐怕是需要我們?cè)趯?shí)踐中不斷磨礪而體會(huì)出來(lái)的。在看完設(shè)計(jì)模式后,不妨反問以下自己,這些模式終究能給你帶來(lái)什么?Interpreter、Iterator、State模式Interpreter模式:這個(gè)模式主要試圖去解釋一種語(yǔ)言。如果你學(xué)過形式語(yǔ)言,那么這個(gè)模式對(duì)你來(lái)說是多余的。Iterator模式:這個(gè)模式試圖隱藏集合的部表示,又同時(shí)可以使用戶依次訪問集合中的元素?,F(xiàn)在STL和Java的跌代器就是應(yīng)用這個(gè)模式的結(jié)果。State模式:這個(gè)模式的意圖是允許對(duì)象在其狀態(tài)改變時(shí)修改其行為,好似對(duì)象改變了。這個(gè)模式的應(yīng)用場(chǎng)景是當(dāng)對(duì)象的行為依賴于對(duì)象的狀態(tài)時(shí)。為了實(shí)現(xiàn)這個(gè)模式,我們可以為每個(gè)狀態(tài)下的行為實(shí)現(xiàn)一個(gè)類,當(dāng)對(duì)象的狀態(tài)發(fā)生改變,它調(diào)用不同狀態(tài)對(duì)象的實(shí)例方法。注意,以前可能需要使用switch或者if語(yǔ)句進(jìn)展分支轉(zhuǎn)換,現(xiàn)在那么利用多態(tài)機(jī)制完成。Flyweight模式這個(gè)模式利用共享有效的支持大量的細(xì)粒度的對(duì)象。比方,編輯軟件中,一篇文章有很多個(gè)字符,我們可以對(duì)每個(gè)字符對(duì)象生成一個(gè)對(duì)象,如果這篇文章有幾M個(gè)文字,那么對(duì)象的數(shù)量肯定是不能容忍的。使用Flyweight模式,我們將所有的文字對(duì)象共享起來(lái),文章中的字符僅僅是指向共享池中的某個(gè)對(duì)象的索引。在這里要搞清楚一件事情,利用Flyweight模式不會(huì)有效地減少信息的數(shù)量〔也就是軟件的空間開銷〕,因?yàn)闊o(wú)論是否共享,表達(dá)這么多信息所需要的編碼數(shù)量是一定的,所以開銷不會(huì)大幅減小。只是,這個(gè)模式會(huì)減少系統(tǒng)中對(duì)象的數(shù)量,因?yàn)榇罅康膶?duì)象會(huì)被共享。在編輯軟件中,字符對(duì)象被共享,那么一篇文章中的文字,可以按照段落、格式等等進(jìn)展結(jié)組,一組文字構(gòu)成一個(gè)對(duì)象,這樣對(duì)象從單個(gè)文字變成一組文字,數(shù)量大幅減少。在使用Flyweight模式需要注意的一點(diǎn),由于對(duì)象被共享了,因此這些對(duì)象沒有各自的屬性,那么根據(jù)上下文環(huán)境,我們?cè)谑褂眠@些對(duì)象的時(shí)候,必須向它傳遞一些參數(shù)。在編輯軟件中,這些參數(shù)可能就是字體、字號(hào)、顏色等等信息。使用Flyweight模式還有一個(gè)好處,那就是我們可以在不修改系統(tǒng)的情況下增加享元。mand模式mand模式,將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象。這樣,你可以向客戶端發(fā)送不同請(qǐng)求的參數(shù),排隊(duì)或記錄請(qǐng)求,同時(shí)可以支持不能執(zhí)行的請(qǐng)求。在軟件中,不同的模塊、對(duì)象之間經(jīng)常會(huì)各種調(diào)用,或者我們稱之為請(qǐng)求。傳統(tǒng)的方法,我們將請(qǐng)現(xiàn)為函數(shù)調(diào)用。這樣做是最簡(jiǎn)單的方法,但卻在無(wú)形之中增加了模塊之間的耦合度。當(dāng)請(qǐng)求發(fā)生很大變化的時(shí)候,系統(tǒng)將變得很難維護(hù)。與此同時(shí),當(dāng)效勞端〔承受請(qǐng)求的一端〕增加或者刪除一個(gè)請(qǐng)求的時(shí)候,按照傳統(tǒng)的方法,客戶端〔發(fā)送請(qǐng)求的一端〕也必須重新編譯〔這一點(diǎn)在刪除請(qǐng)求的時(shí)候最明顯〕,這樣系統(tǒng)才能正確運(yùn)行。使用mand模式的一個(gè)核心思想就是,效勞端提供一個(gè)統(tǒng)一的請(qǐng)求處理接口,客戶端那么通過調(diào)用接口向效勞端發(fā)送請(qǐng)求,這些請(qǐng)求被封裝成對(duì)象的形式〔或者其等價(jià)形式〕。在"設(shè)計(jì)模式"中,"四人團(tuán)〞并沒有強(qiáng)調(diào)統(tǒng)一接口的事情,它強(qiáng)調(diào)了另一個(gè)方面,那就是封裝請(qǐng)求。事實(shí)上,封裝一個(gè)請(qǐng)求總是要求有一個(gè)地方來(lái)承受和處理這個(gè)請(qǐng)求的,這個(gè)地方實(shí)際上就是統(tǒng)一請(qǐng)求接口。在"設(shè)計(jì)模式"中,請(qǐng)求被封裝成一個(gè)mand對(duì)象,這個(gè)對(duì)象保存著請(qǐng)求類型、參數(shù)等信息,效勞端收到這個(gè)命令后就會(huì)執(zhí)行mand對(duì)象中的Execute()函數(shù),這個(gè)函數(shù)具體實(shí)現(xiàn)了真正的操作。這種實(shí)現(xiàn)方法可以保證增加新的請(qǐng)求而不必重新編譯效勞端。我個(gè)人認(rèn)為,mand模式的另一個(gè)形式就是在效勞端實(shí)現(xiàn)各種操作,mand對(duì)象只是負(fù)責(zé)指明請(qǐng)求的類型,這樣,當(dāng)效勞器端發(fā)現(xiàn)請(qǐng)求不正確時(shí),可以忽略該請(qǐng)求。和上一種形式相比,這種形式更加簡(jiǎn)潔〔因?yàn)榭梢圆徽嬲龑?shí)現(xiàn)mand對(duì)象,在C++中可以使用不定參數(shù)實(shí)現(xiàn)〕,但是缺少靈活性。mand模式使得記錄請(qǐng)求成為了可能,我們可以捕獲系統(tǒng)中的請(qǐng)求對(duì)象,記錄他們。posite模式posite模式的意圖是"將對(duì)象組合成樹形構(gòu)造表示‘整體-局部’的層次構(gòu)造。posite使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用更具有一致性〞。在Word中我們經(jīng)常會(huì)將一些圖元進(jìn)展"組合〞,組合以后的圖形還可以向簡(jiǎn)單圖元那樣進(jìn)展移動(dòng)、變形等等操作;除此以外,在Word中,我們對(duì)于一個(gè)字符、一個(gè)詞組、一句話、一個(gè)段落,甚至是整篇文章的操作是一樣的,我們都可以進(jìn)展剪切、復(fù)制,進(jìn)展字體與大小的調(diào)整,進(jìn)展顏色的變換。這些例子都是posite模式的實(shí)例,我們將簡(jiǎn)單的元素組合成復(fù)雜的元素,然后還可以像操作簡(jiǎn)單元素那樣操作組合元素。posite模式將子元素組織成樹型,實(shí)際上,組織成圖型也沒有問題。用戶總是喜歡組合簡(jiǎn)單元素,一方面,用戶可以通過這樣的組合來(lái)進(jìn)展抽象,另一方面,用戶可以通過組合化簡(jiǎn)繁瑣的操作。posite模式在各種可視化編輯軟件中應(yīng)用得最為廣泛。另一使用posite的經(jīng)典例子是Java的Swing系統(tǒng)。所有的Swing組件都是繼承自一個(gè)叫做Jponent的接口,因此,我們對(duì)一個(gè)JFrame的操作和對(duì)一個(gè)utton的操作是一樣的。這同時(shí)也使得,JFrame在管理自己的子元素時(shí),它不需要知道他們是一個(gè)utton還是一個(gè)JPanel,對(duì)它來(lái)說,這只是一個(gè)Jponent。實(shí)現(xiàn)posite模式的關(guān)鍵是良好設(shè)計(jì)的接口,人們應(yīng)該對(duì)可能的元素〔簡(jiǎn)單的、組合的〕進(jìn)展分析,并設(shè)計(jì)出通用的操作。盡可能的保證接口操作對(duì)所有元素都是有意義的,否那么就應(yīng)該將那些只對(duì)局部元素有意義的操作下放到子類中。Proxy模式按照"四人團(tuán)〞的說法,Proxy模式可以為控制另一個(gè)對(duì)象而提供一個(gè)代理或者占位符。這個(gè)模式可以使我們?cè)谡嬲枰臅r(shí)候創(chuàng)立對(duì)象,如果我們不需要這個(gè)對(duì)象,Proxy模式會(huì)為我們提供一個(gè)占位符。如果我們有大量這樣消耗很大的對(duì)象的時(shí)候,我們就可以使用Proxy模式,初始情況下,Proxy模式只會(huì)提供占位符而不會(huì)真正創(chuàng)立對(duì)象,但是對(duì)于使用者來(lái)說,他看到是真正的對(duì)象而不是一個(gè)代理。一旦使用者需要獲得或者更改對(duì)象屬性的時(shí)候,Proxy模式就會(huì)創(chuàng)立該對(duì)象,在此之后,我們就可以通過代理訪問真正的對(duì)象了。在Word里面應(yīng)該是使用了Proxy模式。翻開一篇含圖的很長(zhǎng)的文檔時(shí),大局部的圖片都不會(huì)被載入,而僅僅是提供占位符,只有當(dāng)用戶準(zhǔn)備觀察這一頁(yè)的時(shí)候,代理才會(huì)真正載入圖片。和Singleton模式一樣,Proxy模式都是保證我們可以按需分配對(duì)象,不同的是,Singleton模式還會(huì)保證在全局圍使用同一個(gè)對(duì)象實(shí)例,而Proxy那么沒有這個(gè)功能。Visitor模式按照"四人團(tuán)〞的說法,Visitor模式的意圖為:將元素的操作表示成一種構(gòu)造。這樣Visitor模式可以使你在不修改元素構(gòu)造的前提下增加新的操作??紤]一個(gè)鏈表,我們需要一個(gè)求得最大元素的操作,這個(gè)操作可能是遍歷每個(gè)節(jié)點(diǎn),然后求的最大值。這個(gè)時(shí)候我們又需要一個(gè)為每個(gè)元素加1的操作,這個(gè)操作還需要遍歷每個(gè)節(jié)點(diǎn),同時(shí)將每個(gè)元素加1。與之類似,還會(huì)有很多其他的針對(duì)元素操作,他們的特點(diǎn)都是要遍歷鏈表。這個(gè)時(shí)候可以使用Visitor模式,結(jié)點(diǎn)類負(fù)責(zé)依次遍歷,并調(diào)用Visitor類中的函數(shù),而Visitor類的具體實(shí)現(xiàn)那么負(fù)責(zé)完成功能。這里需要注意的是,Visitor類只能是一個(gè)接口,針對(duì)不同的操作需要有不同的具體實(shí)現(xiàn),針對(duì)不同的具體元素,需要設(shè)計(jì)不同的操作。每個(gè)元素負(fù)責(zé)選擇自己應(yīng)該調(diào)用的操作,Visitor子類負(fù)責(zé)實(shí)現(xiàn)具體功能。一個(gè)的應(yīng)用是SmallTalk-80的編譯器,在編譯時(shí),編譯器需要建立一棵語(yǔ)法樹。在這個(gè)時(shí)候,它使用了Visitor模式,針對(duì)不同的操作,比方:類型檢查、代碼生成等操作實(shí)現(xiàn)不同的Visitor具體類,Visitor類中針對(duì)不同的節(jié)點(diǎn)類型提供不同的操作接口,具體的節(jié)點(diǎn)負(fù)責(zé)選擇調(diào)用哪種接口,這像是一種回調(diào)操作。Observer模式按照"四人團(tuán)〞的說法,Observer模式的意圖是"定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新〞。實(shí)際應(yīng)用的例子是,比方建模工具中,假設(shè)干條線形元素附著在一個(gè)塊狀元素上,當(dāng)塊狀元素的大小、位置發(fā)生變化,那些線形元素也需要進(jìn)展改變,這個(gè)時(shí)候我們就可以應(yīng)用Observer模式,在塊狀元素和線形元素之間建立一對(duì)多的關(guān)系,并利用這一模式進(jìn)展維護(hù)。Observer模式首先構(gòu)造一個(gè)Observer類,在這個(gè)類中具有一個(gè)update函數(shù)。被依賴的對(duì)象擁有它,依賴的對(duì)象被注冊(cè)到Observer中,當(dāng)被依賴的對(duì)象發(fā)生變化的時(shí)候,就調(diào)用update函數(shù)更新所有依賴它的對(duì)象。更新的方式由update函數(shù)具體實(shí)現(xiàn)。還有一個(gè)現(xiàn)實(shí)中的例子,各個(gè)部門之間進(jìn)展通訊,當(dāng)一方發(fā)出新的信息時(shí),按照傳統(tǒng)的方法它必須告訴所有其他部門。如果使用Observer模式,那么產(chǎn)生新消息的一方只需要告知Observer,由Observer通知其他方面。TemplateMethod模式TemplateMethod模式的意圖是:"定義一個(gè)操作中的骨架,而將一些步驟延遲到子類中。這使得子類可以不改變一個(gè)算法的構(gòu)造即可以重定義該算法的某些特定步驟。這一模式和Strategy模式似乎和相似,但是他們的關(guān)注點(diǎn)不同。策略模式主要用于算法的替換,但是模板方法模式主要用于算法中特定步驟地替換。一個(gè)應(yīng)用模板方法模式的例子是數(shù)據(jù)庫(kù)操作。對(duì)于數(shù)據(jù)庫(kù)操作可以有很多中,比方查詢、更新。查詢又可以分為連接數(shù)據(jù)庫(kù)、發(fā)送請(qǐng)求命令、解析結(jié)果等等步驟。對(duì)于不同的數(shù)據(jù)庫(kù),比方Oracle和SQL2000,它們連接數(shù)據(jù)庫(kù)、命令格式可能有所不同,但是就查詢和更新著兩個(gè)操作來(lái)說它們的步驟是一樣的。這個(gè)時(shí)候,我們可以應(yīng)用模板方法模式,為查詢、更新操作建立一個(gè)抽象的算法,具體的步驟交給子類來(lái)實(shí)現(xiàn)。如果對(duì)于策略模式,我們替換的將是查詢和更新著兩個(gè)操作。但是,將TemplateMethod模式和Strategy模式進(jìn)展類比是危險(xiǎn)的,這兩個(gè)模式有著很多重要的不同,但這些不同卻又是十分的細(xì)微,只能意會(huì)不能言傳。FactoryMethod模式這一模式的意圖是:"定義一個(gè)用于創(chuàng)立對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類。FactoryMethod是一個(gè)類的實(shí)例化延遲到其子類。〞這一模式的關(guān)鍵是掌握"何時(shí)應(yīng)用這一模式〞,事實(shí)上我覺得這也是所有設(shè)計(jì)模式的關(guān)鍵。一個(gè)的應(yīng)用就是MFC中關(guān)于Document和Frame之間的關(guān)系。通常在生成一個(gè)多文檔程序時(shí),VC會(huì)為你創(chuàng)立一個(gè)Frame類和Document類,你的Frame類可以用來(lái)相應(yīng)OnFileNew消息,然后創(chuàng)立一個(gè)Document對(duì)象。但是對(duì)于Windows的消息系統(tǒng)來(lái)說,它并不知道用戶程序中創(chuàng)立的Document類有什么特性,對(duì)于它來(lái)說,它所看到是CFrame對(duì)象和CDocument對(duì)象。FactoryMethod模式可以保證其他對(duì)象不需要知道具體對(duì)象的類型而管理這些對(duì)象,這一模式通常用于制定框架。這一模式和AbstractFactory模式很相像,事實(shí)上AbstractFactory模式可以由一系列FactoryMethod模式實(shí)現(xiàn)。Strategy模式Strategy模式的目的就是"定義一系列的算法,把他們一個(gè)個(gè)封裝起來(lái),并且使他們可以互相替換。〞如何理解這一模式,首先看下面這個(gè)場(chǎng)景:一組數(shù)據(jù)進(jìn)展排序,我們可以選擇很多中排序算法,這個(gè)時(shí)候我們定義一個(gè)排序策略,然后每個(gè)排序算法實(shí)現(xiàn)一個(gè)具體策略,這樣用戶就可以在幾個(gè)不同的排序算法中隨意選擇和替換了。當(dāng)然,上面的例子中使用策略模式似乎多此一舉,那么假設(shè)游戲中的敵人的AI,根據(jù)玩家的設(shè)定可以有不同的級(jí)別。在這種情況下,使用策略模式就是十分必要的了。Bridge模式按照"四人團(tuán)〞的說法,Bridge模式的意圖是:將抽象局部與他的實(shí)現(xiàn)局部別離,使得他們可以獨(dú)立的變化。你一定會(huì)感到一陣眩暈,不明白這是什么意思。首先應(yīng)該說明的是"抽象〞與"實(shí)現(xiàn)〞的含義。在剛剛的那句話中,"抽象〞與"實(shí)現(xiàn)〞并不是我們?cè)诿枋鲱悩?gòu)造時(shí)所說的"接口〞與它的"實(shí)現(xiàn)〞,或者在Java中抽象類與他的實(shí)現(xiàn)。在這里,"抽象〞與"實(shí)現(xiàn)〞只得是某種工作,"抽象〞是說如何完成這項(xiàng)工作,"實(shí)現(xiàn)〞是說"抽象〞中所用的步驟的實(shí)現(xiàn)。一個(gè)例子可以很好的說明"抽象〞與"實(shí)現(xiàn)〞的關(guān)系。我們編寫一個(gè)游戲,這個(gè)游戲有兩個(gè)版本,DX版本和OpenGL版本。我們?nèi)绾尉帉戇@兩個(gè)版本呢?一種方法是我們?cè)谶@兩個(gè)引擎上開發(fā)兩套獨(dú)立的游戲,但這顯然不是最好的方法。另一個(gè)選擇是我們將游戲的"抽象〞局部與"實(shí)現(xiàn)〞局部別離,開發(fā)一套"抽象〞局部,開發(fā)兩套"實(shí)現(xiàn)〞局部。那么什么是游戲的"抽象〞局部?很顯然就是游戲的繪圖〔也許用更專業(yè)詞匯的應(yīng)該是:渲染〕過程,例如我們?nèi)绾武秩居螒虻娜宋铮@個(gè)人物可能是由很多個(gè)多邊形組合而成的,我們按照一定的方法渲染之后,就可以畫出一個(gè)人物來(lái)。這一局部就可以看作是"抽象〞。那么另一方面就是"實(shí)現(xiàn)〞局部,在上面的例子中,"實(shí)現(xiàn)〞局部就是如何繪制根底的線條、填充顏色,甚至是初始化屏幕等等。這些"實(shí)現(xiàn)〞和具體的引擎密切相關(guān)。為什么說我們可以將"抽象〞和"實(shí)現(xiàn)〞別離,使得他們可以各自變化呢?假設(shè)現(xiàn)在要開發(fā)新的游戲,或者這個(gè)游戲升級(jí)了,在其中出現(xiàn)了新的人物,那么"抽象〞局部就發(fā)生了變化,但是具體"實(shí)現(xiàn)〞沒有變化,因此這個(gè)游戲還可以繼續(xù)在你的計(jì)算機(jī)上運(yùn)行。另一方面,如果游戲需要進(jìn)展移植,目標(biāo)平臺(tái)的圖形系統(tǒng)發(fā)生了變化,你可能需要使用新的繪圖引擎,這個(gè)時(shí)候,你只需要利用新的引擎實(shí)現(xiàn)根本的"實(shí)現(xiàn)〞操作,原始的程序就可以在新的平臺(tái)上運(yùn)行〔略去重新編譯的問題〕。Facade模式Facade模式的目的就是給子系統(tǒng)提供一個(gè)統(tǒng)一的接口?,F(xiàn)在的軟件都是按照模塊進(jìn)展劃分,對(duì)不同的模塊分別進(jìn)展編程。但是在用戶開來(lái),不同的模塊應(yīng)該具有統(tǒng)一的接口,換句話說,我們應(yīng)該可以通過統(tǒng)一的接口訪問系統(tǒng)中的所有功能。有一個(gè)很典型的例子就是編譯系統(tǒng)。通常我們將編譯系統(tǒng)分解為:pile和Link兩個(gè)步驟。一個(gè)pile又可以分解為詞法分析、語(yǔ)法分析、語(yǔ)義分析、中間代碼生成等等步驟。對(duì)于用戶來(lái)講,我們不可能將這些模塊分別提供應(yīng)他們,讓他們依次調(diào)用。相反的,我們應(yīng)該提供一個(gè)統(tǒng)一的接口,使得用戶可以方便的使用各個(gè)功能,例如IDE。Facade模式在強(qiáng)調(diào)模塊化開發(fā)的同時(shí)也強(qiáng)調(diào)模塊的統(tǒng)一,統(tǒng)一的接口也有利于子系統(tǒng)中模塊部的變化。對(duì)于開發(fā)大型系統(tǒng)來(lái)說,F(xiàn)acade模式是不可缺少的。Decorator模式按照"四人團(tuán)〞的說法,Decorator模式的意圖是:動(dòng)態(tài)的給一個(gè)對(duì)象添加一些額外的職責(zé)。值得注意的是,這個(gè)對(duì)象不知道他增加的是什么職責(zé)。這個(gè)模式的一個(gè)典型應(yīng)用實(shí)例是:Java的流。一個(gè)文件流〔Java.IO.File〕用于讀寫文件,如果你想使用文件緩沖,你可在為File添加一個(gè)BufferedInputStream或者BufferedOutputStream外觀,這樣這個(gè)文件流就具有了緩沖。再如一個(gè)Reader類,你可以給他增加緩沖BufferedReader,然后你還可以給這個(gè)緩沖流增加一些格式化讀取的能力。Decorator模式可以動(dòng)態(tài)的增加對(duì)象的額外的職責(zé),這也有利于將額外的功能分別實(shí)現(xiàn),使得用戶可以自由組合。Adapter模式有一天你在網(wǎng)上找到一個(gè)庫(kù),你打算把它應(yīng)用到你的程序當(dāng)中去,但是你發(fā)現(xiàn)這個(gè)庫(kù)的函數(shù)不符合你的風(fēng)格,你會(huì)怎么辦?一個(gè)很簡(jiǎn)單的方法就是使用Adapter模式。Adapter模式的目的就是將一個(gè)類的接口轉(zhuǎn)換為用戶希望的接口,使得由于接口不兼容而不能一起工作的各個(gè)類可以一起工作。例如在一個(gè)軟件里面可能使用了以前一個(gè)版本的類庫(kù)。不幸的是這個(gè)類庫(kù)的效率極高卻和現(xiàn)在的接口不兼容,為了繼續(xù)復(fù)用這個(gè)類庫(kù)我們就可以使用Adapter模式,在原來(lái)的類庫(kù)和現(xiàn)在的接口中間實(shí)現(xiàn)一個(gè)適配器,使得我們可以用現(xiàn)在的構(gòu)造調(diào)用以前的類庫(kù)。例如一個(gè)繪圖程序〔這種事情總是出現(xiàn)在這類程序中〕,以前的類庫(kù)中提供繪制直線的方法DrawLine,但是新的接口要求繪圖系統(tǒng)還要提供繪制矩形、折線形的方法,為了復(fù)用這個(gè)類庫(kù),我們實(shí)現(xiàn)一個(gè)Adapter類,這個(gè)類中利用以前的繪圖系統(tǒng)提供的方法實(shí)現(xiàn)了新的接口功能。Singleton模式這可能是最簡(jiǎn)單的一個(gè)模式了,但是他的應(yīng)用卻是最多的。這個(gè)模式的目的就是保證一個(gè)對(duì)象只有一個(gè)實(shí)例,并且提供一個(gè)全局的訪問點(diǎn)。那么這個(gè)模式的怎么實(shí)現(xiàn)呢?很簡(jiǎn)單,你首先必須為這個(gè)類設(shè)置一個(gè)指針〔Java中是引用〕,然后提供一個(gè)方法用來(lái)獲得這個(gè)類的實(shí)例。在這個(gè)方法中首先判斷這個(gè)指針是否為空,如果是,那么創(chuàng)立一個(gè)實(shí)例,否那么直接返回這個(gè)指針。雖然我們可以提供一個(gè)全局訪問點(diǎn),但實(shí)際上這個(gè)模式也可以應(yīng)用到局部。應(yīng)用這個(gè)模式一個(gè)好處就是可以"按需分配〞,同時(shí)也封裝了對(duì)象的獲取過程。不管如何,我覺得應(yīng)該盡可能的應(yīng)用這個(gè)模式,雖然這會(huì)讓你感到很煩……這個(gè)模式在實(shí)現(xiàn)過程中可以進(jìn)展變化,例如在Instance()方法上添加參數(shù)BooleanbAlloc,用于指定當(dāng)實(shí)例不存在的時(shí)候是否進(jìn)展創(chuàng)立。這樣做是考慮到,有些時(shí)候我們獲得實(shí)例的目的不是為了修改,而是為了讀取。這個(gè)時(shí)候,返回一個(gè)空實(shí)例和返回一個(gè)沒有被修改正的實(shí)例在邏輯上是一樣的。例如,這個(gè)對(duì)象是一個(gè)數(shù)組時(shí),一個(gè)"空數(shù)組〞和一個(gè)"空白的數(shù)組〞是一樣的。Builder模式按照"四人團(tuán)〞的說法,Builder模式的目的是:將一個(gè)復(fù)雜對(duì)象的構(gòu)建與他的表示別離,使得同樣的構(gòu)建過程可以創(chuàng)立不同的表示。一個(gè)典型的例子是:文件的格式轉(zhuǎn)換。假設(shè)一個(gè)RTF文件,我們可以將它轉(zhuǎn)換成不同的格式,比方TXT、DOC、PDF等等。在這些目標(biāo)格式的文件中,有些文件格式中保存文本字體〔比方DOC〕,有些可能不保存〔比方TXT〕。當(dāng)我們開場(chǎng)轉(zhuǎn)換過程時(shí),按照RTF文件自己的格式進(jìn)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論