Java設(shè)計(jì)模式:結(jié)構(gòu)型模式(代理模式,適配器模式等)_第1頁(yè)
Java設(shè)計(jì)模式:結(jié)構(gòu)型模式(代理模式,適配器模式等)_第2頁(yè)
Java設(shè)計(jì)模式:結(jié)構(gòu)型模式(代理模式,適配器模式等)_第3頁(yè)
Java設(shè)計(jì)模式:結(jié)構(gòu)型模式(代理模式,適配器模式等)_第4頁(yè)
Java設(shè)計(jì)模式:結(jié)構(gòu)型模式(代理模式,適配器模式等)_第5頁(yè)
已閱讀5頁(yè),還剩14頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、結(jié)構(gòu)型模式前面創(chuàng)建型模式介紹了創(chuàng)建對(duì)象的一些設(shè)計(jì)模式,這節(jié)介紹的結(jié)構(gòu)型模式旨在通過(guò)改變代碼結(jié)構(gòu)來(lái)達(dá)到解耦的目的,使得我們的代碼容易維護(hù)和擴(kuò)展。代理模式第一個(gè)要介紹的代理模式是最常使用的模式之一了,用一個(gè)代理來(lái)隱藏具體實(shí)現(xiàn)類的實(shí)現(xiàn)細(xì)節(jié),通常還用于在真實(shí)的實(shí)現(xiàn)的前后添加一部分邏輯。既然說(shuō)是代理,那就要對(duì)客戶端隱藏真實(shí)實(shí)現(xiàn),由代理來(lái)負(fù)責(zé)客戶端的所有請(qǐng)求。當(dāng)然,代理只是個(gè)代理,它不會(huì)完成實(shí)際的業(yè)務(wù)邏輯,而是一層皮而已,但是對(duì)于客戶端來(lái)說(shuō),它必須表現(xiàn)得就是客戶端需要的真實(shí)實(shí)現(xiàn)。理解代理這個(gè)詞,這個(gè)模式其實(shí)就簡(jiǎn)單了。publicinterfaceFoodServiceFoodmakeChicken();F

2、oodmakeNoodle();publicclassFoodServiceImplimplementsFoodServicepublicFoodmakeChicken()Foodf=newChicken()f.setChicken(1kg);f.setSpicy(1g);f.setSalt(3g);returnf;publicFoodmakeNoodle()Foodf=newNoodle();f.setNoodle(500g);f.setSalt(5g);returnf;/代理要表現(xiàn)得“就像是”真實(shí)實(shí)現(xiàn)類,所以需要實(shí)現(xiàn)FoodServicepublicclassFoodServiceProx

3、yimplementsFoodService/內(nèi)部一定要有一個(gè)真實(shí)的實(shí)現(xiàn)類,當(dāng)然也可以通過(guò)構(gòu)造方法注入privateFoodServicefoodService=newFoodServiceImpl();publicFoodmakeChicken()System.out.println(我們馬上要開(kāi)始制作雞肉了”);/如果我們定義這句為核心代碼的話,那么,核心代碼是真實(shí)實(shí)現(xiàn)類做的,/代理只是在核心代碼前后做些“無(wú)足輕重”的事情Foodfood=foodService.makeChicken();System.out.println(雞肉制作完成啦,加點(diǎn)胡椒粉);/增強(qiáng)food.addCondi

4、ment(pepper);returnfood;publicFoodmakeNoodle()System.out.println(”準(zhǔn)備制作拉面”);Foodfood=foodService.makeNoodle();System.out.println(制作完成啦)returnfood;客戶端調(diào)用,注意,我們要用代理來(lái)實(shí)例化接口:/這里用代理類來(lái)實(shí)例化FoodServicefoodService=newFoodServiceProxy();foodService.makeChicken();代理模式:我們發(fā)現(xiàn)沒(méi)有,代理模式說(shuō)白了就是做“方法包裝”或做“方法增強(qiáng)”。在面向切面編程中,算了還是不

5、要吹捧這個(gè)名詞了,在AOP中,其實(shí)就是動(dòng)態(tài)代理的過(guò)程。比如Spring中,我們自己不定義代理類,但是Spring會(huì)幫我們動(dòng)態(tài)來(lái)定義代理,然后把我們定義在Before、After、Around中的代碼邏輯動(dòng)態(tài)添加到代理中。說(shuō)到動(dòng)態(tài)代理,又可以展開(kāi)說(shuō)Spring中實(shí)現(xiàn)動(dòng)態(tài)代理有兩種,一種是如果我們的類定義了接口,如UserService接口和UserServicelmpl實(shí)現(xiàn),那么采用JDK的動(dòng)態(tài)代理,感興趣的讀者可以去看看java.lang.reflect.Proxy類的源碼;另一種是我們自己沒(méi)有定義接口的,Spring會(huì)采用CGLIB進(jìn)行動(dòng)態(tài)代理,它是一個(gè)jar包,性能還不錯(cuò)。適配器模式說(shuō)完代

6、理模式,說(shuō)適配器模式,是因?yàn)樗鼈兒芟嗨?,這里可以做個(gè)比較。適配器模式做的就是,有一個(gè)接口需要實(shí)現(xiàn),但是我們現(xiàn)成的對(duì)象都不滿足,需要加一層適配器來(lái)進(jìn)行適配。適配器模式總體來(lái)說(shuō)分三種:默認(rèn)適配器模式、對(duì)象適配器模式、類適配器模式。先不急著分清楚這幾個(gè),先看看例子再說(shuō)。默認(rèn)適配器模式首先,我們先看看最簡(jiǎn)單的適配器模式默認(rèn)適配器模式(DefaultAdapter)是怎么樣的。我們用Appachecommons-io包中的FileAlterationListener做例子,此接口定義了很多的方法,用于對(duì)文件或文件夾進(jìn)行監(jiān)控,一旦發(fā)生了對(duì)應(yīng)的操作,就會(huì)觸發(fā)相應(yīng)的方法。publicinterfaceFile

7、AlterationListenervoidonStart(finalFileAlterationObserverobserver);voidonDirectoryCreate(finalFiledirectory);voidonDirectoryChange(finalFiledirectory);voidonDirectoryDelete(finalFiledirectory);voidonFileCreate(finalFilefile);voidonFileChange(finalFilefile);voidonFileDelete(finalFilefile);voidonStop(

8、finalFileAlterationObserverobserver);此接口的一大問(wèn)題是抽象方法太多了,如果我們要用這個(gè)接口,意味著我們要實(shí)現(xiàn)每一個(gè)抽象方法,如果我們只是想要監(jiān)控文件夾中的文件創(chuàng)建和文件刪除事件,可是我們還是不得不實(shí)現(xiàn)所有的方法,很明顯,這不是我們想要的。所以,我們需要下面的一個(gè)適配器,它用于實(shí)現(xiàn)上面的接口,但是所有的方法都是空方法,這樣,我們就可以轉(zhuǎn)而定義自己的類來(lái)繼承下面這個(gè)類即可。publicclassFileAlterationListenerAdaptorimplementsFileAlterationListenerpublicvoidonStart(final

9、FileAlterationObserverobserver)publicvoidonDirectoryCreate(finalFiledirectory)publicvoidonDirectoryChange(finalFiledirectory)publicvoidonDirectoryDelete(finalFiledirectory)publicvoidonFileCreate(finalFilefile)publicvoidonFileChange(finalFilefile)publicvoidonFileDelete(finalFilefile)publicvoidonStop(

10、finalFileAlterationObserverobserver)比如我們可以定義以下類,我們僅僅需要實(shí)現(xiàn)我們想實(shí)現(xiàn)的方法就可以了publicclassFileMonitorextendsFileAlterationListenerAdaptorpublicvoidonFileCreate(finalFilefile)/文件創(chuàng)建doSomething();publicvoidonFileDelete(finalFilefile)/文件刪除doSomething();當(dāng)然,上面說(shuō)的只是適配器模式的其中一種,也是最簡(jiǎn)單的一種,無(wú)需多言。下面再介紹“正統(tǒng)的”適配器模式。對(duì)象適配器模式來(lái)看一個(gè)H

11、eadFirst設(shè)計(jì)模式中的一個(gè)例子,我稍微修改了一下,看看怎么將雞適配成鴨,這樣雞也能當(dāng)鴨來(lái)用。因?yàn)椋F(xiàn)在鴨這個(gè)接口,我們沒(méi)有合適的實(shí)現(xiàn)類可以用,所以需要適配器。publicinterfaceDuckpublicvoidquack();/鴨的呱呱叫publicvoidfly();/飛publicinterfaceCockpublicvoidgobble();/雞的咕咕叫publicvoidfly();/飛publicclassWildCockimplementsCockpublicvoidgobble()System.out.println(”咕咕叫”);publicvoidfly()Sys

12、tem.out.println(雞也會(huì)飛哦”);鴨接口有fly()和quare()兩個(gè)方法,雞Cock如果要冒充鴨,fly()方法是現(xiàn)成的,但是雞不會(huì)鴨的呱呱叫,沒(méi)有quack()方法。這個(gè)時(shí)候就需要適配了:/毫無(wú)疑問(wèn),首先,這個(gè)適配器肯定需要implementsDuck,這樣才能當(dāng)做鴨來(lái)用publicclassCockAdapterimplementsDuckCockcock;/構(gòu)造方法中需要一個(gè)雞的實(shí)例,此類就是將這只雞適配成鴨來(lái)用publicCockAdapter(Cockcock)this.cock=cock;/實(shí)現(xiàn)鴨的呱呱叫方法Overridepublicvoidquack()/內(nèi)部

13、其實(shí)是一只雞的咕咕叫cock.gobble();Overridepublicvoidfly()cock.fly();客戶端調(diào)用很簡(jiǎn)單了:publicstaticvoidmain(Stringargs)/有一只野雞CockwildCock=newWildCock();/成功將野雞適配成鴨Duckduck=newCockAdapter(wildCock);到這里,大家也就知道了適配器模式是怎么回事了。無(wú)非是我們需要一只鴨,但是我們只有一只雞,這個(gè)時(shí)候就需要定義一個(gè)適配器,由這個(gè)適配器來(lái)充當(dāng)鴨,但是適配器里面的方法還是由雞來(lái)實(shí)現(xiàn)的。我們用一個(gè)圖來(lái)簡(jiǎn)單說(shuō)明下:上圖應(yīng)該還是很容易理解的,我就不做更多的解

14、釋了。下面,我們看看類適配模式怎么樣的。類適配器模式廢話少說(shuō),直接上圖:看到這個(gè)圖,大家應(yīng)該很容易理解的吧,通過(guò)繼承的方法,適配器自動(dòng)獲得了所需要的大部分方法。這個(gè)時(shí)候,客戶端使用更加簡(jiǎn)單,直接Targett=newSomeAdapter();就可以了。適配器模式總結(jié)1.類適配和對(duì)象適配的異同一個(gè)采用繼承,一個(gè)采用組合;類適配屬于靜態(tài)實(shí)現(xiàn),對(duì)象適配屬于組合的動(dòng)態(tài)實(shí)現(xiàn),對(duì)象適配需要多實(shí)例化一個(gè)對(duì)象??傮w來(lái)說(shuō),對(duì)象適配用得比較多。2.適配器模式和代理模式的異同比較這兩種模式,其實(shí)是比較對(duì)象適配器模式和代理模式,在代碼結(jié)構(gòu)上,它們很相似,都需要一個(gè)具體的實(shí)現(xiàn)類的實(shí)例。但是它們的目的不一樣,代理模式做

15、的是增強(qiáng)原方法的活;適配器做的是適配的活,為的是提供“把雞包裝成鴨,然后當(dāng)做鴨來(lái)使用”,而雞和鴨它們之間原本沒(méi)有繼承關(guān)系。適配器模式-時(shí)魚(yú)適配HSU體對(duì)注人到話配吐申,幫助話方広interfaceTarget丫口idmethodlQ;voidmethodZO;voidncthodJt)c怎強(qiáng)SdrneThingvoidrtiethodO_voidmethadJO_classSomeAdapterimplementTargetpmvcZSoraThlngs;月陸申ilApubli匚SEfieAdaptcrCSOTeThingis)this.5-a;widnthsidic)/此分法訝目ma丹梏買現(xiàn)

16、voidnthodiOs.msthadsO;-/題戰(zhàn)萬(wàn)注voidmethodic?saiwthod30-/取成方法classSrviclrriplimplementServicevoidmethodUO_widMthMjiO_voidirrethmlBC)_classServiceProxyiinplerneriitServicepriwort?Sprwi*rvi|耳Inpliwr5rwirFCispIC52widjnethodlO_;servicelrrt?l.rrethodlOvoidmethadZQ_;servicelmpl.methodZO;voidmethadiO_;servicel

17、mplintcrfaLServicevoidnelhodlOLvoidfletho歐);voidnethodSOi橋梁模式理解橋梁模式,其實(shí)就是理解代碼抽象和解耦。我們首先需要一個(gè)橋梁,它是一個(gè)接口,定義提供的接口方法+x+publicinterfaceDrawAPIpublicvoiddraw(intradius,intx,inty);然后是一系列實(shí)現(xiàn)類:publicclassRedPenimplementsDrawAPIOverridepublicvoiddraw(intradius,intx,inty)System.out.println(用紅色筆畫(huà)圖,radius:+radius+,x

18、:,y:+y);publicclassGreenPenimplementsDrawAPIOverridepublicvoiddraw(intradius,intx,inty)System.out.println(用綠色筆畫(huà)圖,radius:+radius+,x:,y:+y);publicclassBluePenimplementsDrawAPIOverridepublicvoiddraw(intradius,intx,inty)System.out.println(用藍(lán)色筆畫(huà)圖,radius:+radius+,x:,y:+y);定義一個(gè)抽象類,此類的實(shí)現(xiàn)類都需要使用DrawAPI:public

19、abstractclassShapeprotectedDrawAPIdrawAPI;protectedShape(DrawAPIdrawAPI)this.drawAPI=drawAPI;publicabstractvoiddraw();定義抽象類的子類:/圓形publicclassCircleextendsShapeprivateintradius;publicCircle(intradius,DrawAPIdrawAPI)super(drawAPI);this.radius=radius;publicvoiddraw()drawAPI.draw(radius,0,0);/長(zhǎng)方形publicc

20、lassRectangleextendsShapeprivateintx;privateinty;publicRectangle(intx,inty,DrawAPIdrawAPI)super(drawAPI);this.x=x;this.y=y;publicvoiddraw()drawAPI.draw(0,x,y);最后,我們來(lái)看客戶端演示:publicstaticvoidmain(Stringargs)ShapegreenCircle=newCircle(10,newGreenPen();ShaperedRectangle=newRectangle(4,8,newRedPen();green

21、Circle.draw();redRectangle.draw();可能大家看上面一步步還不是特別清晰,我把所有的東西整合到一張圖上:這回大家應(yīng)該就知道抽象在哪里,怎么解耦了吧。橋梁模式的優(yōu)點(diǎn)也是顯而易見(jiàn)的,就是非常容易進(jìn)行擴(kuò)展。本節(jié)引用了這里的例子,并對(duì)其進(jìn)行了修改。裝飾模式要把裝飾模式說(shuō)清楚明白,不是件容易的事情。也許讀者知道JavalO中的幾個(gè)類是典型的裝飾模式的應(yīng)用,但是讀者不一定清楚其中的關(guān)系,也許看完就忘了,希望看完這節(jié)后,讀者可以對(duì)其有更深的感悟。首先,我們先看一個(gè)簡(jiǎn)單的圖,看這個(gè)圖的時(shí)候,了解下層次結(jié)構(gòu)就可以了:我們來(lái)說(shuō)說(shuō)裝飾模式的出發(fā)點(diǎn),從圖中可以看到,接口Component

22、其實(shí)已經(jīng)有了ConcreteComponentA和ConcreteComponentB兩個(gè)實(shí)現(xiàn)類了,但是,如果我們要增強(qiáng)這兩個(gè)實(shí)現(xiàn)類的話,我們就可以采用裝飾模式,用具體的裝飾器來(lái)裝飾實(shí)現(xiàn)類,以達(dá)到增強(qiáng)的目的。從名字來(lái)簡(jiǎn)單解釋下裝飾器。既然說(shuō)是裝飾,那么往往就是添加小功能這種,而且,我們要滿足可以添加多個(gè)小功能。最簡(jiǎn)單的,代理模式就可以實(shí)現(xiàn)功能的增強(qiáng),但是代理不容易實(shí)現(xiàn)多個(gè)功能的增強(qiáng),當(dāng)然你可以說(shuō)用代理包裝代理的方式,但是那樣的話代碼就復(fù)雜了。首先明白一些簡(jiǎn)單的概念,從圖中我們看到,所有的具體裝飾者們ConcreteDecorator_都可以作為Component來(lái)使用,因?yàn)樗鼈兌紝?shí)現(xiàn)了Comp

23、onent中的所有接口。它們和Component實(shí)現(xiàn)類ConcreteComponent_的區(qū)別是,它們只是裝飾者,起裝飾作用,也就是即使它們看上去牛逼轟轟,但是它們都只是在具體的實(shí)現(xiàn)中加了層皮來(lái)裝飾而已。注意這段話中混雜在各個(gè)名詞中的Component和Decorator,別搞混了。下面來(lái)看看一個(gè)例子,先把裝飾模式弄清楚,然后再介紹下javaio中的裝飾模式的應(yīng)用。最近大街上流行起來(lái)了“快樂(lè)檸檬”,我們把快樂(lè)檸檬的飲料分為三類:紅茶、綠茶咖啡,在這三大類的基礎(chǔ)上,又增加了許多的口味,什么金桔檸檬紅茶、金桔檸檬珍珠綠茶、芒果紅茶、芒果綠茶、芒果珍珠紅茶、烤珍珠紅茶、烤珍珠芒果綠茶、椰香胚芽咖啡

24、、焦糖可可咖啡等等,每家店都有很長(zhǎng)的菜單,但是仔細(xì)看下,其實(shí)原料也沒(méi)幾樣,但是可以搭配出很多組合,如果顧客需要,很多沒(méi)出現(xiàn)在菜單中的飲料他們也是可以做的。在這個(gè)例子中,紅茶、綠茶、咖啡是最基礎(chǔ)的飲料,其他的像金桔檸檬、芒果、珍珠、椰果、焦糖等都屬于裝飾用的。當(dāng)然,在開(kāi)發(fā)中,我們確實(shí)可以像門店一樣,開(kāi)發(fā)這些類:LemonBlackTea、LemonGreenTea、MangoBlackTea、MangoLemonGreenTea但是,很快我們就發(fā)現(xiàn),這樣子干肯定是不行的,這會(huì)導(dǎo)致我們需要組合出所有的可能,而且如果客人需要在紅茶中加雙份檸檬怎么辦?三份檸檬怎么辦?萬(wàn)一有個(gè)變態(tài)要四份檸檬,所以這種做

25、法是給自己找加班的。不說(shuō)廢話了,上代碼。首先,定義飲料抽象基類:publicabstractclassBeverage/返回描述publicabstractStringgetDescription();/返回價(jià)格publicabstractdoublecost();然后是三個(gè)基礎(chǔ)飲料實(shí)現(xiàn)類,紅茶、綠茶和咖啡:publicclassBlackTeaextendsBeveragepublicStringgetDescription()return紅茶;publicdoublecost()return10;publicclassGreenTeaextendsBeveragepublicStringg

26、etDescription()return綠茶;publicdoublecost()return11;./咖啡省略定義調(diào)料,也就是裝飾者的基類,此類必須繼承自Beverage:/調(diào)料publicabstractclassCondimentextendsBeverage然后我們來(lái)定義檸檬、芒果等具體的調(diào)料,它們屬于裝飾者,毫無(wú)疑問(wèn),這些調(diào)料肯定都需要繼承Condiment類:publicclassLemonextendsCondimentprivateBeveragebevarage;/這里很關(guān)鍵,需要傳入具體的飲料,如需要傳入沒(méi)有被裝飾的紅茶或綠茶,/當(dāng)然也可以傳入已經(jīng)裝飾好的芒果綠茶,這樣可

27、以做芒果檸檬綠茶publicLemon(Beveragebevarage)this.bevarage=bevarage;publicStringgetDescription()/裝飾returnbevarage.getDescription()+,加檸檬;publicdoublecost()/裝飾returnbeverage.cost()+2;/加檸檬需要2元publicclassMangoextendsCondimentprivateBeveragebevarage;publicMango(Beveragebevarage)this.bevarage=bevarage;publicStrin

28、ggetDescription()returnbevarage.getDescription()+,加芒果;publicdoublecost()returnbeverage.cost()+3;/加芒果需要3元./給每一種調(diào)料都加一個(gè)類看客戶端調(diào)用:publicstaticvoidmain(Stringargs)/首先,我們需要一個(gè)基礎(chǔ)飲料,紅茶、綠茶或咖啡Beveragebeverage=newGreenTea();/開(kāi)始裝飾beverage=newLemon(beverage);/先加一份檸檬beverage=newMongo(beverage);/再加一份芒果System.out.prin

29、tln(beverage.getDescription()+價(jià)格:+beverage.cost();/綠茶,加檸檬,加芒果價(jià)格:16如果我們需要芒果珍珠雙份檸檬紅茶:Beveragebeverage=newMongo(newPearl(newLemon(newLemon(newBlackTea();是不是很變態(tài)?看看下圖可能會(huì)清晰一些:到這里,大家應(yīng)該已經(jīng)清楚裝飾模式了吧。下面,我們?cè)賮?lái)說(shuō)說(shuō)javalO中的裝飾模式??聪聢DInputstream派生出來(lái)的部分類:裝飾器Java10中的裝飾模式PipedInputStreamFibrinputStreamex怕InputStreamByteArr

30、aylnputStreamFllelnputStrearnInputstreamLiineNumbeflnputSfrearnBufferedlnputStreannDatalnputStreani我們知道InputStream代表了輸入流,具體的輸入來(lái)源可以是文件(FileInputStream)、管道(PipedlnputStream)、數(shù)組(ByteArraylnputStream)等,這些就像前面奶茶的例子中的紅茶、綠茶,屬于基礎(chǔ)輸入流。FilterInputStream承接了裝飾模式的關(guān)鍵節(jié)點(diǎn),其實(shí)現(xiàn)類是一系列裝飾器,比如BufferedInputStream代表用緩沖來(lái)裝飾,也就使

31、得輸入流具有了緩沖的功能,LineNumberlnputStream代表用行號(hào)來(lái)裝飾,在操作的時(shí)候就可以取得行號(hào)了,DataInputStream的裝飾,使得我們可以從輸入流轉(zhuǎn)換為java中的基本類型值。當(dāng)然,在javaIO中,如果我們使用裝飾器的話,就不太適合面向接口編程了,如:InputStreaminputStream=newLineNumberInputStream(newBufferedInputStream(newFileInputStream();這樣的結(jié)果是,InputStream還是不具有讀取行號(hào)的功能,因?yàn)樽x取行號(hào)的方法定義在LineNumberlnputStream類中。

32、我們應(yīng)該像下面這樣使用:DataInputStreamisnewDataInputStream(newBufferedInputStream(newFileInputStream();所以說(shuō)嘛,要找到純的嚴(yán)格符合設(shè)計(jì)模式的代碼還是比較難的。門面模式門面模式(也叫外觀模式,F(xiàn)acadePattern)在許多源碼中有使用,比如slf4j就可以理解為是門面模式的應(yīng)用。這是一個(gè)簡(jiǎn)單的設(shè)計(jì)模式,我們直接上代碼再說(shuō)吧。首先,我們定義一個(gè)接口:publicinterfaceShapevoiddraw();定義幾個(gè)實(shí)現(xiàn)類:publicclassCircleimplementsShapeOverridepubl

33、icvoiddraw()System.out.println(Circle:draw();publicclassRectangleimplementsShapeOverridepublicvoiddraw()System.out.println(Rectangle:draw();客戶端調(diào)用:publicstaticvoidmain(Stringargs)/畫(huà)一個(gè)圓形Shapecircle=newCircle();circle.draw();/畫(huà)一個(gè)長(zhǎng)方形Shaperectangle=newRectangle();rectangle.draw();以上是我們常寫(xiě)的代碼,我們需要畫(huà)圓就要先實(shí)例化圓

34、,畫(huà)長(zhǎng)方形就需要先實(shí)例化一個(gè)長(zhǎng)方形,然后再調(diào)用相應(yīng)的draw()方法。下面,我們看看怎么用門面模式來(lái)讓客戶端調(diào)用更加友好一些。我們先定義一個(gè)門面:publicclassShapeMakerprivateShapecircle;privateShaperectangle;privateShapesquare;publicShapeMaker()circle=newCircle();rectangle=newRectangle();square=newSquare();*下面定義一堆方法,具體應(yīng)該調(diào)用什么方法,由這個(gè)門面來(lái)決定*/publicvoiddrawCircle()circle.draw(

35、);publicvoiddrawRectangle()rectangle.draw();publicvoiddrawSquare()square.draw();看看現(xiàn)在客戶端怎么調(diào)用:publicstaticvoidmain(Stringargs)ShapeMakershapeMaker=newShapeMaker();/客戶端調(diào)用現(xiàn)在更加清晰了shapeMaker.drawCircle();shapeMaker.drawRectangle();shapeMaker.drawSquare();門面模式的優(yōu)點(diǎn)顯而易見(jiàn),客戶端不再需要關(guān)注實(shí)例化時(shí)應(yīng)該使用哪個(gè)實(shí)現(xiàn)類,直接調(diào)用門面提供的方法就可以了,因?yàn)殚T面類提供的方法的方

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝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ù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 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)論