




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
歡迎來到星巴茲咖啡星巴茲(Starbuzz)是以擴張速度最快而聞名的咖啡連鎖店。如果你在街角看到它的店,在對面街上肯定還會看到另一家。每個子類實現cost()這個名為description(敘述)料,例如“超優深焙cost()歡迎來到星巴茲咖啡星巴茲(Starbuzz)是以擴張速度最快而聞名的咖啡連鎖店。如果你在街角看到它的店,在對面街上肯定還會看到另一家。每個子類實現cost()這個名為description(敘述)料,例如“超優深焙cost()//其他有用的方法購買咖啡時,也可以要求在其中加入各種調料,例如:蒸奶(SteamedMilk)、豆漿(Soy)、摩卡(Mocha,也就是巧克力風味)或覆蓋奶泡。星巴茲會根據所加入的調料收取不同的費anDarkRoastWithWDecafWithWHouseBlendWHouseBlendWithSEDDarkRoastWi//其他有用的方法……購買咖啡時,也可以要求在其中加入各種調料,例如:蒸奶(SteamedMilk)、豆漿(Soy)、摩卡(Mocha,也就是巧克力風味)或覆蓋奶泡。星巴茲會根據所加入的調料收取不同的費anDarkRoastWithWDecafWithWHouseBlendWHouseBlendWithSEDDarkRoastWi//其他有用的方法……好吧!就來試試看。先從Beverage基類下手,加上實例變量代表是否加上調料(牛奶、豆漿、摩卡、奶泡爾好吧!就來試試看。先從Beverage基類下手,加上實例變量代表是否加上調料(牛奶、豆漿、摩卡、奶泡爾//其他有用的方法……很明顯,星巴茲為自己制造了一個維護惡夢。如果牛奶的價錢上揚,怎么辦?新增一種焦糖調料風味時,怎么辦?每個cost()請為下面類的cost()方法書寫代碼(用偽Java代碼即可)每個cost()請為下面類的cost()方法書寫代碼(用偽Java代碼即可)publicclassBeverage{ publicdoublecost(){publicdoublecost() //其他有用的方法……當哪些需求或因素改變時會影響這個設計?一旦出現新的調料,我們就需要加上新的方法,并改變超類中的cost()當哪些需求或因素改變時會影響這個設計?一旦出現新的調料,我們就需要加上新的方法,并改變超類中的cost()門徒:大師,我已經了解到利用組合(composition)和委托(delegation)門徒:利用繼承設計子類的行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴展對象的行為,就可以在門徒:大師,我已經了解到利用組合(composition)和委托(delegation)門徒:利用繼承設計子類的行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴展對象的行為,就可以在門徒:這正是我要說的。通過動態地組合對象,可以寫新的代碼添加新功能,而無須修改現有代碼。既然沒有改變現有代碼,那么引進bug或產生意外副作用的機樣地開放(能夠擴展)開放-關閉原則你想要的行為來擴展我們的類。如果你的需要或需求有所改變(我們知道這一定會發生的),那就來吧!動手擴展吧!們花了許多時間得到了正確的代碼,還解決了所有的bug,所以不能讓你修改現有代碼。我們必須關閉代碼以防止被修改。如果你不喜歡,可以找經理談。開放-關閉原則你想要的行為來擴展我們的類。如果你的需要或需求有所改變(我們知道這一定會發生的),那就來吧!動手擴展吧!們花了許多時間得到了正確的代碼,還解決了所有的bug,所以不能讓你修改現有代碼。我們必須關閉代碼以防止被修改。如果你不喜歡,可以找經理談。hrearohrearo問:問:答:答:通常,你辦不到。要讓OO計同時具備開放性和關閉性,又不修改現有的代碼,需要花費許多時間和努力。一般來說,我們實在沒有閑工夫把設計的每個部分都這么設計(而且,就算做得到,也可能只是一種浪費)。遵循開放-關閉原則,通常會引入新的抽象層次,增加代碼的復雜度。你需要把注意力集中在設計中最有可能改變的地方,然后應用開放-關閉行為的其他OO問:問:好吧!我了解觀察者-able),答:這牽涉到設計OO答:夠了!你們這些“面向對象設計俱樂部”的家伙??靵斫鉀Q真正的問題吧!還記得我們嗎?星巴茲咖啡?你認為這些設計原則有實質的幫助嗎?認識好了,我們已經了解利用繼承無法完全解決問題,在星巴茲遇到的問題有:類數量爆炸、設計死板,以及基類加入的新功能并不適用于所拿一個深焙咖啡(DarkRoast)以摩卡(Mocha)以奶泡(Whip)夠了!你們這些“面向對象設計俱樂部”的家伙??靵斫鉀Q真正的問題吧!還記得我們嗎?星巴茲咖啡?你認為這些設計原則有實質的幫助嗎?認識好了,我們已經了解利用繼承無法完全解決問題,在星巴茲遇到的問題有:類數量爆炸、設計死板,以及基類加入的新功能并不適用于所拿一個深焙咖啡(DarkRoast)以摩卡(Mocha)以奶泡(Whip)調用cost()方法,并依賴委托(delegate)好了!但是如何“裝飾”一個對象,而“委托”又要如何與此搭配使用呢?給一個暗示:把裝飾者對象當成“包裝者”。讓我們看看這是以裝飾者構造飲料訂單以DarkRoast顧客想要摩卡(Mocha),Mocha對象,并用它將DarkRoast(wrap)顧客也想要奶泡(Whip),所以需要建立一個Whip裝飾者,并用它將Mocha別忘了,DarkRoast繼承自Beverage,且有一個cost()所以,被Mocha和Whip包起來的DarkRoast以裝飾者構造飲料訂單以DarkRoast顧客想要摩卡(Mocha),Mocha對象,并用它將DarkRoast(wrap)顧客也想要奶泡(Whip),所以需要建立一個Whip裝飾者,并用它將Mocha別忘了,DarkRoast繼承自Beverage,且有一個cost()所以,被Mocha和Whip包起來的DarkRoast型)Mocha映”了它所裝飾的對象(現在,該是為顧客算錢的時候了。通過調用最外圈裝飾者(Whip)的cost()以辦得到。Whip的cost()會先委托它裝飾的對象(也就是Mocha)計算出價錢,然后再加上奶泡的價錢。Mocha調用DarkRoastcost()好了,這是目前所知道的一切……既然裝飾者和被裝飾對象有相同的超類型,所以在任何需要原始對象(被包裝的) 裝飾者可以在所委托被裝飾者的行為之前與/現在,就來看看的定義,并寫一些代碼,了解它到底是怎么工作的。Whip調用Mocha的cost()現在,該是為顧客算錢的時候了。通過調用最外圈裝飾者(Whip)的cost()以辦得到。Whip的cost()會先委托它裝飾的對象(也就是Mocha)計算出價錢,然后再加上奶泡的價錢。Mocha調用DarkRoastcost()好了,這是目前所知道的一切……既然裝飾者和被裝飾對象有相同的超類型,所以在任何需要原始對象(被包裝的) 裝飾者可以在所委托被裝飾者的行為之前與/現在,就來看看的定義,并寫一些代碼,了解它到底是怎么工作的。Whip調用Mocha的cost()首先,調用最外圈裝Whip的cost()DrakRoast返回它錢$0.99Mocha在DarkRoast加上自己的價錢$0.20,的價錢$1.19定義實際“應用”它。我們來看看類圖,會有些幫助(結構套用在飲料問題上)象,它擴展自Component口(也可以是抽象類)(裝飾者包著的Component)ComponentObjectnewState定義實際“應用”它。我們來看看類圖,會有些幫助(結構套用在飲料問題上)象,它擴展自Component口(也可以是抽象類)(裝飾者包著的Component)ComponentObjectnewStateComponent動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更有彈性的替代方案。裝飾我們的飲料BeverageComponentBeverageBeverageBeverageBeverage裝飾我們的飲料BeverageComponentBeverageBeverageBeverageBeverage辦公室隔間對話Sue:Mary:看看類圖。CondimentDecorator擴展自BeverageSue:的確是如此,但我認為,這么做的重點在于,裝飾者和被裝飾者必須是一樣的類型,也就是有共同的超類,這是相當關鍵的地方。在這里,我們利用繼承達到“類型匹配”,而不是利Mary:我知道為何裝飾者需要和被裝飾者(亦即被包裝的組件)Sue:Mary:好的。繼承BeverageSue:辦公室隔間對話Sue:Mary:看看類圖。CondimentDecorator擴展自BeverageSue:的確是如此,但我認為,這么做的重點在于,裝飾者和被裝飾者必須是一樣的類型,也就是有共同的超類,這是相當關鍵的地方。在這里,我們利用繼承達到“類型匹配”,而不是利Mary:我知道為何裝飾者需要和被裝飾者(亦即被包裝的組件)Sue:Mary:好的。繼承BeverageSue:Mary:Sue:是的。如果依賴繼承,那么類的行為只能在編譯時靜態決定。換句話說,行如果不是來自超類,就是子類覆蓋后的版本。反之,利用組合,可以把裝飾者混合著用……而且是在“運行Mary:Sue:Mary:我還剩下一個問題,如果我們需要繼承的是component類型,為什么不Beverage類設計成Sue:關于這個嘛,還記得嗎?當初我們從星巴茲拿到這個程序時,Beverage“是采用抽象類,但是在Java新咖啡師傅特訓如果有一張單子點的是:“雙倍摩卡豆漿奶泡拿鐵咖啡”,請使用菜單得到正確的價錢并畫一個圖來表達OK,Whip調用Mocha的cost首先,調用最新咖啡師傅特訓如果有一張單子點的是:“雙倍摩卡豆漿奶泡拿鐵咖啡”,請使用菜單得到正確的價錢并畫一個圖來表達OK,Whip調用Mocha的cost首先,調用最者Whip的cost()DrakRoast價錢$0.99Mocha在DarkRoast錢上,再加上自己的$0.20錢,返回新的價錢$1.19寫下星巴茲的代碼先從Beverage寫下星巴茲的代碼先從Beveragereturndescription;Beverage很簡單。讓我們也來實現Condiment(調料publicabstractclassCondimentDecoratorextendsBeveragepublicabstractStringgetDescription();但是cost()首先,必須讓CondimentDecorator夠取代Beverage,所以將類Decorator寫飲料的代碼publicEspresso(){return1.99;publicHouseBlend(){寫飲料的代碼publicEspresso(){return1.99;publicHouseBlend(){return.89;返回正確的價錢$0.89樣咖綜深低咖啡因濃配牛摩豆奶首先,讓Espresso格$1.99descriptionBeverage寫調料代碼件(Beverage),有了具體組件(HouseBlend),也有了抽象裝飾者(CondimentDecorator)。現在,我們就來實現具體裝飾者。先從摩卡下手:publicclassMochaextendsCondimentDecorator{Beveragebeverage;publicMocha(Beveragebeverage){this.beverage=beverage;publicStringgetDescription(){+",寫調料代碼件(Beverage),有了具體組件(HouseBlend),也有了抽象裝飾者(CondimentDecorator)。現在,我們就來實現具體裝飾者。先從摩卡下手:publicclassMochaextendsCondimentDecorator{Beveragebeverage;publicMocha(Beveragebeverage){this.beverage=beverage;publicStringgetDescription(){+",publicdoublecost()return.20+寫下Soy和Whip要計算帶Mocha上Mocha供應咖啡恭喜你,是時候舒服地坐下來,點一些咖啡,看看你利用設計出的靈活系統是多么神奇了。publicclassStarbuzzCoffeepublicstaticvoidmain(Stringargs[]){Beveragebeverage=newEspresso();+"$"+Beveragebeverage2=供應咖啡恭喜你,是時候舒服地坐下來,點一些咖啡,看看你利用設計出的靈活系統是多么神奇了。publicclassStarbuzzCoffeepublicstaticvoidmain(Stringargs[]){Beveragebeverage=newEspresso();+"$"+Beveragebeverage2=new+"$"+Beveragebeverage3=new+"$"+制造出一個DarkRoast用Mocha最后,再來一杯調料為卡、奶泡的HouseBlendFileEditWindowHelpEspresso$1.99beverage3=newbeverage3=newMocha(beverage3);beverage3=newWhip(beverage3);beverage2=newMocha(beverage2);beverage2=newMocha(beverage2);beverage2=newWhip(beverage2);hrearo如果我將代碼針對特定種類的具體組件(例如House-Blend),做一些特殊的事(例hrearo如果我將代碼針對特定種類的具體組件(例如House-Blend),做一些特殊的事(例如,打折),我擔心這樣的設計是否恰當。因為一旦用裝飾者包裝HouseBlend,裝飾者該做的事,就是增加行為到被包裝對象上。當需要窺視裝飾者鏈中的每一個裝飾者時,這就超出他們的天賦了。但是,并不是做不到??梢詫懸粋€CondimentPrettyPrint裝飾者,解析出最后的描述字符串,然后把“Mocha,WhipMocha”變成“Whip,DoubleMocha”。如果能把getDescription()的返回值變成答:你當然可以爭辯說,使答:的確是這樣。如果你把問:裝飾者知道這一連串裝飾鏈條中其他裝飾者的存在嗎?比出“Whip,DoubleMocha”而不是“Mocha,Whip,Mocha”,這需要問:對于使用到飲料的某些我們在星巴茲的朋友決定開始在菜單上加上咖啡的容量大小,供顧客這是任何咖啡都必須具備的,所以在Beverage類中加上了getSize()與加上豆漿,分別加收0.10、0.15、0.20美金。JavaI/O真實世界的裝飾者:JavaI/Ojava.io包內的類太多了,簡直是……“排山倒?!?。你第一次(還有第二次和第三次)看到這些API發出“哇”的驚嘆時,放心,你不是唯一受到驚嚇的人。現,這些I/O中許多類都是裝飾者。下面是一個典型的對象集合,用裝飾者來將功能結合起來,以讀取文件數據:BufferedInputStream及LineNumberInputStreamFilterInputStream,而FilterInputStreamJavaI/O真實世界的裝飾者:JavaI/Ojava.io包內的類太多了,簡直是……“排山倒海”。你第一次(還有第二次和第三次)看到這些API發出“哇”的驚嘆時,放心,你不是唯一受到驚嚇的人。現,這些I/O中許多類都是裝飾者。下面是一個典型的對象集合,用裝飾者來將功能結合起來,以讀取文件數據:BufferedInputStream及LineNumberInputStreamFilterInputStream,而FilterInputStreamI/O讀取一行文本輸入數據)裝飾java.io類你可以發現,和星巴茲的設計相比,java.io其實沒有多大的差異。我們把java.ioAPI范圍縮小,讓你容易查看它的文件,并組合各種“輸你會發現“輸出”流的設計方式也是一樣的。你可能還會發現Writer流(作為基于字符數據的輸入輸出)和輸入流/輸出流的類相當類似(雖然有一些小差異和不一致之處,但是相當雷同,所以你應該可以了解這些類)但是JavaI/O常造成設計中有大量的小類,數量實在太多,可能會造成使用此API程序員的困擾。但是,現在你已經了解了裝飾者的工作原理,以后當使用別人的大量裝飾的API時,就可以很容易地辨別出他們的裝飾者類是如這些InputStream裝飾java.io類你可以發現,和星巴茲的設計相比,java.io其實沒有多大的差異。我們把java.ioAPI范圍縮小,讓你容易查看它的文件,并組合各種“輸你會發現“輸出”流的設計方式也是一樣的。你可能還會發現Writer流(作為基于字符數據的輸入輸出)和輸入流/輸出流的類相當類似(雖然有一些小差異和不一致之處,但是相當雷同,所以你應該可以了解這些類)但是JavaI/O常造成設計中有大量的小類,數量實在太多,可能會造成使用此API程序員的困擾。但是,現在你已經了解了裝飾者的工作原理,以后當使用別人的大量裝飾的API時,就可以很容易地辨別出他們的裝飾者類是如這些InputStreamObjectInputStream編寫自己的JavaI/O編寫自己的JavaI/0裝飾者你已經知道,也看過JavaI/O類圖,應該已經準備好編寫自己的輸入裝飾者了。沒問題,我只要擴展FilterInputStream類,并覆蓋read()方法就行了!這個想法怎么樣:編寫一個裝飾者,把輸入流內的所有大寫字符轉成小寫。舉例:當讀取“Iknow編寫自己的JavaI/O編寫自己的JavaI/0裝飾者你已經知道,也看過JavaI/O類圖,應該已經準備好編寫自己的輸入裝飾者了。沒問題,我只要擴展FilterInputStream類,并覆蓋read()方法就行了!這個想法怎么樣:編寫一個裝飾者,把輸入流內的所有大寫字符轉成小寫。舉例:當讀取“IknowtheDecoratorPatternthereforeIRULE!”,裝飾者會將它轉成“iknowthedecoratorpatternthereforeirule!”publicLowerCaseInputStream(InputStreamin){publicintread()throwsIOException{intc=super.read();return(c==-1?c:publicintread(byte[]b,intoffset,intlen)throwsIOExceptionintresult=super.read(b,offset,len);for(inti=offset;i<offset+result;i++)b[i]=return不要忘了導入(這里省略了有InputStream現在,必須實現兩個read()的字節(每個代表一個字符測試你的新JavaI/O裝飾者寫個小程序,來測試剛寫好的I/O裝飾者:publicclassInputTestpublicstaticvoidmain(String[]args)throws測試你的新JavaI/O裝飾者寫個小程序,來測試剛寫好的I/O裝飾者:publicclassInputTestpublicstaticvoidmain(String[]args)throwsIOExceptionintc;tryInputStreaminnewLowerCaseInputStream(newwhile((c=in.read())>=0){}catch(IOExceptione){test.txt運行看看:設置FileInputStream,們嶄新的LowerCaseInputStreamFileEditWindowHelp%javaiknowthedecoratorpatternthereforei模式訪談HeadFirst:HeadFirst:HeadFirst:裝飾者:以JavaI/O他們能認識到這些類都是用來包裝InputStreamHeadFirst:裝飾者:恐怕不只這些,我還有類型問題。有些時候,人們在客戶代碼中依賴某種特殊類型,然后忽然導入裝飾者,卻又沒有周詳地考慮一切?,F在,我的一個優點是,你通常可以透明地插入裝飾者,客戶程序甚至不需知道它是在和裝飾者打交道。但是,如我剛剛所說的,有些代模式訪談HeadFirst:HeadFirst:HeadFirst:裝飾者:以JavaI/O他們能認識到這些類都是用來包裝InputStreamHeadFirst:裝飾者:恐怕不只這些,我還有類型問題。有些時候,人們在客戶代碼中依賴某種特殊類型,然后忽然導入裝飾者,卻又沒有周詳地考慮一切。現在,我的一個優點是,你通??梢酝该鞯夭迦胙b飾者,客戶程序甚至不需知道它是在和裝飾者打交道。但是,如我剛剛所說的,有些代HeadFirst:HeadFirst:我下周會訪談工廠(Factory)模式和生成器(Builder)HeadFirst:設計箱內的工具本章已經接近尾聲,你的工具箱內又多了一個新的原則和一個新的模式。要點抽多繼編起演式OO基礎原模設計箱內的工具本章已經接近尾聲,你的工具箱內又多了一個新的原則和一個新的模式。要點抽多繼編起演式OO基礎原模這是第一個符合開放-關閉原則的式。真的是第一個嗎?有沒有其?繼承屬于擴展形式之一,但不?在我們的設計中,應該允許行?組合和委托可用于在運行時動?除了繼承,也可以 類,這些類用來包裝具體組?裝飾者類反映出被裝飾的組件?裝飾者可以在被裝飾者的行為前面與/或后面加上自己的行為,甚至將被裝飾者的行為?你可以用無數個裝飾者包裝一?裝飾者一般對組件的客戶是透?裝飾者會導致設計中出現許多習題解答Whip調用Mocha的cost()Mocha調用另一個Mocha的cost()接著,Mocha調用Soy的cost()首先,調者Whip的cost()最后,Soy調用HouseBlendcost()習題解答Whip調用Mocha的cost()Mocha調用另一個Mocha的cost()接著,Mocha調用Soy的cost()首先,調者Whip的cost()最后,Soy調用HouseBlendcost()回0.89給Soy后,離Soy的cost()把HouseBlend回的結果加上0.15,Mocha第二個Mocha的cost0.20,返回結果,離返回結果,離開本層新咖啡師傅特 “有雙摩卡、豆漿、奶泡的HouseBlend咖啡 10最后,Whip的cost()把Mocha返回的價錢加上0
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 山東省棗莊市現代實驗學校2024-2025學年高考原創信息試卷物理試題(三)含解析
- 山西省忻州市岢嵐縣中學2025屆高三下學期教學質量調研考試(二模)歷史試題試卷含解析
- 四川托普信息技術職業學院《NoSQ數據庫原理》2023-2024學年第二學期期末試卷
- 上海外國語大秀洲外國語校2024-2025學年初三4月階段性測試語文試題含解析
- 西北師范大學《地方文化研究》2023-2024學年第二學期期末試卷
- 武漢科技大學《印度文化遺產賞析》2023-2024學年第二學期期末試卷
- 上海師范大學《中國古代文學I》2023-2024學年第一學期期末試卷
- 江蘇省高郵市陽光雙語初中重點名校2025年初三最后一考生物試題試卷含解析
- 西安高新科技職業學院《外國史學史》2023-2024學年第一學期期末試卷
- 江蘇省蘇州市東山中學2025年初三5月月考英語試題理試題含答案
- 肝硬化常見并發癥的護理
- 2025年北京市通州區九年級初三一模道德與法治試卷(含答案)
- 惠州一中、珠海一中等六校聯考2024-2025學年高三考前熱身物理試卷含解析
- 所得稅會計試題及答案
- 2025年保安員職業技能考試筆試試題(700題)附答案
- 《知不足而后進 望山遠而力行》期中家長會課件
- 專題09 鄉村和城鎮-五年(2019-2023)高考地理真題分項匯編(解析版)
- 2025年第三屆天揚杯建筑業財稅知識競賽題庫附答案(201-300題)
- 2025年納米鎳粉市場規模分析
- T-NKFA 015-2024 中小學午休課桌椅
- 2024年山東淄博中考滿分作文《從“閱”到“悅”》5
評論
0/150
提交評論