




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(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)類(lèi) 的實(shí)現(xiàn)細(xì)節(jié),通常還用于在真實(shí)的實(shí)現(xiàn)的前后添加一部分邏輯。既然說(shuō)是代理,那就要對(duì)客戶(hù)端隱藏真實(shí)實(shí)現(xiàn),由代理來(lái)負(fù)責(zé)客戶(hù)端的所有請(qǐng)求。 當(dāng)然,代理只是個(gè)代理,它不會(huì)完成實(shí)際的業(yè)務(wù)邏輯,而是一層皮而已,但是對(duì)于 客戶(hù)端來(lái)說(shuō),它必須表現(xiàn)得就是客戶(hù)端需要的真實(shí)實(shí)現(xiàn)。理解代理這個(gè)詞,這個(gè)模式其實(shí)就簡(jiǎn)單了。public interface Foodservice Food makeChi
2、cken();Food makeNoodle();public class FoodserviceImpl implements Foodservice public Food makeChicken() Food f = new Chicken()f.setChicken("1kg");f.setSpicy("1g");f.setSalt("3g");return f;public Food makeNoodle() Food f = new Noodle();f.setNoodle("500g");f.setS
3、alt("5g");return f;/代理要表現(xiàn)得 就像是“真實(shí)實(shí)現(xiàn)類(lèi),所以需要實(shí)現(xiàn)FoodServicepublic class FoodServiceProxy implements FoodService /內(nèi)部一定要有一個(gè)真實(shí)的實(shí)現(xiàn)類(lèi),當(dāng)然也可以通過(guò)構(gòu)造方法注入private FoodService foodService = new FoodServiceImpl();public Food makeChicken() System.out.println("我們馬上要開(kāi)始制作雞肉了 ");/如果我們定義這句為核心代碼的話(huà),那么,核心代碼是真
4、實(shí)實(shí)現(xiàn)類(lèi)做的,/代理只是在核心代碼前后做些無(wú)足輕重”的事情Food food = foodService.makeChicken();System.out.println("雞肉制作完成啦,加點(diǎn)胡椒粉 ");/ 增強(qiáng)food.addCondiment("pepper");return food;public Food makeNoodle() System.out.println("準(zhǔn)備制作拉面”);Food food = foodService.makeNoodle();System.out.println("制作完成啦”)retu
5、rn food; 客戶(hù)端調(diào)用,注意,我們要用代理來(lái)實(shí)例化接口:/這里用代理類(lèi)來(lái)實(shí)例化FoodService foodService = new FoodServiceProxy();foodService.makeChicken();我們發(fā)現(xiàn)沒(méi)有,代理模式說(shuō)白了就是做方法包裝”或做 方法增強(qiáng)”。在面向切面編程中,算了還是不要吹捧這個(gè)名詞了,在 AOP中,其實(shí)就是動(dòng)態(tài)代理的過(guò)程。 比如Spring中,我們自己不定義代理類(lèi),但是 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)
6、態(tài)代理有兩種,一種是如果我們 的類(lèi)定義了接口,如 UserService接口和UserServiceImpl實(shí)現(xiàn),那么采用 JDK的 動(dòng)態(tài)代理,感興趣的讀者可以去看看 java.lang.reflect.Proxy類(lèi)的源碼;另一種是我 們自己沒(méi)有定義接口的,Spring會(huì)采用CGLIB進(jìn)行動(dòng)態(tài)代理,它是一個(gè)jar包,性 能還不錯(cuò)。適配器模式說(shuō)完代理模式,說(shuō)適配器模式,是因?yàn)樗鼈兒芟嗨?,這里可以做個(gè)比較。適配器模式做的就是,有一個(gè)接口需要實(shí)現(xiàn),但是我們現(xiàn)成的對(duì)象都不滿(mǎn)足,需要 加一層適配器來(lái)進(jìn)行適配。適配器模式總體來(lái)說(shuō)分三種:默認(rèn)適配器模式、對(duì)象適配器模式、類(lèi)適配器模式。先不急著分清楚這幾個(gè),先
7、看看例子再說(shuō)。默認(rèn)適配器模式首先,我們先看看最簡(jiǎn)單的適配器模式默認(rèn)適配器模式(Default Adapter)是怎么 樣的。我們用 Appache commons-io 包中的 FileAlterationListener 做例子,此接口定義了 很多的方法,用于對(duì)文件或文件夾進(jìn)行監(jiān)控,一旦發(fā)生了對(duì)應(yīng)的操作,就會(huì)觸發(fā)相 應(yīng)的方法。public interface FileAlterationListener void onStart(final FileAlterationObserver observer);void onDirectoryCreate(final File directory
8、);void onDirectoryChange(final File directory);void onDirectoryDelete(final File directory);void onFileCreate(final File file);void onFileChange(final File file);void onFileDelete(final File file);void onStop(final FileAlterationObserver observer);此接口的一大問(wèn)題是抽象方法太多了,如果我們要用這個(gè)接口,意味著我們要實(shí)現(xiàn)每一個(gè)抽象方法,如果我們只是想要
9、監(jiān)控文件夾中的文件創(chuàng)建和文件刪除事件,可是我們還是不得不實(shí)現(xiàn)所有的方法,很明顯,這不是我們想要的。所以,我們需要下面的一個(gè)適配器,它用于實(shí)現(xiàn)上面的接口,但是所有的方法都 是空方法,這樣,我們就可以轉(zhuǎn)而定義自己的類(lèi)來(lái)繼承下面這個(gè)類(lèi)即可。public class FileAlterationListenerAdaptor implements FileAlterationLis tener public void onStart(final FileAlterationObserver observer) public void onDirectoryCreate(final File direc
10、tory) public void onDirectoryChange(final File directory) public void onDirectoryDelete(final File directory) )public void onFileCreate(final File file) )public void onFileChange(final File file) )public void onFileDelete(final File file) )public void onStop(final FileAlterationObserver observer) )比
11、如我們可以定義以下類(lèi),我們僅僅需要實(shí)現(xiàn)我們想實(shí)現(xiàn)的方法就可以了:public class FileMonitor extends FileAlterationListenerAdaptor public void onFileCreate(final File file) /文件創(chuàng)建doSomething();)public void onFileDelete(final File file) /文件刪除doSomething();)當(dāng)然,上面說(shuō)的只是適配器模式的其中一種,也是最簡(jiǎn)單的一種,無(wú)需多言。下面, 再介紹 正統(tǒng)的“適配器模式。對(duì)象適配器模式來(lái)看一個(gè)Head First設(shè)計(jì)模式中的一個(gè)
12、例子,我稍微修改了一下,看看怎么將 雞適配成鴨,這樣雞也能當(dāng)鴨來(lái)用。因?yàn)?,現(xiàn)在鴨這個(gè)接口,我們沒(méi)有合適的實(shí)現(xiàn) 類(lèi)可以用,所以需要適配器。public interface Duck public void quack(); /鴨的呱呱叫public void fly(); /飛)public interface Cock public void gobble(); /雞的咕咕叫public void fly(); /飛public class WildCock implements Cock public void gobble() System.out.println("咕咕叫)pu
13、blic void fly() System.out.println("雞也會(huì)飛哦");鴨接口有fly()和quare()兩個(gè)方法,雞Cock如果要冒充鴨,fly()方法是現(xiàn)成的, 但是雞不會(huì)鴨的呱呱叫,沒(méi)有 quack()方法。這個(gè)時(shí)候就需要適配了:/毫無(wú)疑問(wèn),首先,這個(gè)適配器肯定需要implements Duck ,這樣才能當(dāng)做鴨來(lái)用public class CockAdapter implements Duck Cock cock;/構(gòu)造方法中需要一個(gè)雞的實(shí)例,此類(lèi)就是將這只雞適配成鴨來(lái)用public CockAdapter(Cock cock) this.cock
14、= cock;/實(shí)現(xiàn)鴨的呱呱叫方法Overridepublic void quack() /內(nèi)部其實(shí)是一只雞的咕咕叫cock.gobble();Override public void fly() cock.fly();客戶(hù)端調(diào)用很簡(jiǎn)單了:public static void main(String args) / 有一只野雞Cock wildCock = new WildCock();/成功將野雞適配成鴨Duck duck = new CockAdapter(wildCock);到這里,大家也就知道了適配器模式是怎么回事了。無(wú)非是我們需要一只鴨,但是 我們只有一只雞,這個(gè)時(shí)候就需要定義一個(gè)適
15、配器,由這個(gè)適配器來(lái)充當(dāng)鴨,但是 適配器里面的方法還是由雞來(lái)實(shí)現(xiàn)的。我們用一個(gè)圖來(lái)簡(jiǎn)單說(shuō)明下:inb Target void methodlCXvoid methodZO;void methodO;class SomeThing void metfiodZJ .J void methodSC)clds SomeAdapter implement Target private 5口一口1110/1忙治中逵入public ScneAdupter(SomeThing s) this-s = s,; void methodic _ " it方法將自己想辦法冥理 void rrethodZCJ
16、 s nethod£C); / 霓成方法 void rwthcdiQ s.m<?thod3C);“現(xiàn)成方法 _胃且體時(shí)薇注入到適配品中,聞助適配器實(shí)理部分方法上圖應(yīng)該還是很容易理解的,我就不做更多的解釋了。下面,我們看看類(lèi)適配模式 怎么樣的。類(lèi)適配器模式廢話(huà)少說(shuō),直接上圖:Target void metkicdlC);void metliod2();void n*ethod3();class SomeThing Void methodZC) 1- void methodSC) . J Lclass ScmeAdapter extends SomeThing implement
17、Target void methodic -“ 叱方法潺自己想辦法實(shí)班獷詞過(guò)隼承.自就獲得了 SomeThing中的mathodSO和e或hW3。祈個(gè)方法看到這個(gè)圖,大家應(yīng)該很容易理解的吧,通過(guò)繼承的方法,適配器自動(dòng)獲得了所需 要的大部分方法。這個(gè)時(shí)候,客戶(hù)端使用更加簡(jiǎn)單,直接 Target t = new SomeAdapter();就可以了。適配器模式總結(jié)1 .類(lèi)適配和對(duì)象適配的異同一個(gè)采用繼承,一個(gè)采用組合;類(lèi)適配屬于靜態(tài)實(shí)現(xiàn),對(duì)象適配屬于組合的動(dòng)態(tài)實(shí)現(xiàn),對(duì)象適配需要多實(shí)例化一個(gè)對(duì)象。總體來(lái)說(shuō),對(duì)象適配用得比較多。2 .適配器模式和代理模式的異同比較這兩種模式,其實(shí)是比較對(duì)象適配器模式和
18、代理模式,在代碼結(jié)構(gòu)上,它 們很相似,都需要一個(gè)具體的實(shí)現(xiàn)類(lèi)的實(shí)例。但是它們的目的不一樣,代理模 式做的是增強(qiáng)原方法的活;適配器做的是適配的活,為的是提供把雞包裝成鴨,然后當(dāng)做鴨來(lái)使用”,而雞和鴨它們之間原本沒(méi)有繼承關(guān)系。代以IB式:r ih'i S"¥l8> wxiA fwthodlQ; votdigidclwt Sarvicelmpl implement Senrice ("id wthodlO .Jvoid metlw正。_)void thodiiO (-1ServiceProxy implement Service (gid FtkHfiL。
19、* i iervicelRpl. wl hgdlQ i«!void FM血匕用1void srethadBC) _:servicel*pl.metho3C):intcrfac- Target void mcttodlO;void mt Md?。;void methodiseJ;區(qū)配箱at式時(shí)第遇配cla#. 50mM由ip%r implement Tnrgtjt (pnwffH 5mni|ne e;pu± 1 ic SofieAdhpterCkcrreThin9 s) tfiii-s s; gid iMrthodiO /成方在得自己揖辦通其理 27 MthCd2O .IHt
20、n6d20; / 孤雇而活 void H3。Is rthwi3OJ 仃雙方潔cIh-: - SomeTtiing gid methc1d飄 void rrethodiO _卜工同4£鼠,三人封法配唐中.幫助通制也克坦郡妙方密橋梁模式理解橋梁模式,其實(shí)就是理解代碼抽象和解耦。我們首先需要一個(gè)橋梁,它是一個(gè)接口,定義提供的接口方法。public interface DrawAPI public void draw(int radius, int x, int y); )然后是一系列實(shí)現(xiàn)類(lèi):public class RedPen implements DrawAPI Overridepub
21、lic void draw(int radius, int x, int y) System.out.println("用紅色筆畫(huà)圖,radius:" + radius + ", x:" + x +",y:" + y);)public class GreenPen implements DrawAPI Overridepublic void draw(int radius, int x, int y) System.out.println("用綠色筆畫(huà)圖,radius:" + radius + ", x:
22、" + x +",y:" + y);)public class BluePen implements DrawAPI Overridepublic void draw(int radius, int x, int y) System.out.println("用藍(lán)色筆畫(huà)圖,radius:" + radius + ", x:" + x +",y:" + y);)定義一個(gè)抽象類(lèi),此類(lèi)的實(shí)現(xiàn)類(lèi)都需要使用 DrawAPI:public abstract class Shape protected DrawAPI
23、drawAPI;protected Shape(DrawAPI drawAPI) this.drawAPI = drawAPI;)public abstract void draw();)定義抽象類(lèi)的子類(lèi):/圓形public class Circle extends Shape private int radius;public Circle(int radius, DrawAPI drawAPI) super(drawAPI);this.radius = radius;)public void draw() drawAPI.draw(radius, 0, 0);)/長(zhǎng)方形public cla
24、ss Rectangle extends Shape private int x;private int y;public Rectangle(int x, int y, DrawAPI drawAPI) super(drawAPI);this.x = x;this.y = y;)public void draw() drawAPI.draw(0, x, y);)最后,我們來(lái)看客戶(hù)端演示:public static void main(String args) Shape greenCircle = new Circle(10, new GreenPen();Shape redRectangl
25、e = new Rectangle(4, 8, new RedPen();greenCircle.draw(); redRectangle.draw();)可能大家看上面一步步還不是特別清晰,我把所有的東西整合到一張圖上:public abstract class Snape (acted DrawAPl drawAF I;pnotMted Shspe>awAP| diiwAPI)| th s.dra-API - draw APRpublic abitiiKl void drawfl;Putxc titans ClrJe Sti;s|h:'.Hit raduB.><加
26、2 CkciBlk¥l raJnis. DrajAFI dranMAPTi M呻僮岫弁晦例熊a心*m蟹vo。dktwG draAPi drawfradius_ 0, OrP而qHR inC戢prh-Me irW y;public Reclaftflleiint x,y qkmapn??﹚np ;, supBrldrsmAPlKIhu»工總/圖¥y:)public void 由i drEAPtmi州,&也橋梁模式 橋梁使用public int6rfjtfl Ek aw API (public mid dramtt mdlu, ini.N.ini y).pUt
27、>iaCr C1 Afli# RedPdinpffevAPI (BOverride pub! ic vaj.d diEiw4 mt r ad i as. in t 工. in t. yj Sy«ter-Qul .prlnllnlra4iu«s* + f*diuH L 苒爐.public cl««B GreenPen LrRpl*rnentB 口營(yíng)盤(pán)冒用工0&¥-»£Adepu-blic void int radiu xnt 國(guó)審 int y J (Systsm.Qua primLn廠用姆包裳四,.radiuss
28、" + radius + x P mspublic =1 SlMFcn intplwantB DcawAJFI 中g(shù)右事工*日電P-D1lg void dr»w(int radiusP int kv i nt y)(System.out.1 o (h %Jbfflr rsdluat41 * radius * /1r 乳營(yíng)誓.這回大家應(yīng)該就知道抽象在哪里,怎么解耦了吧。橋梁模式的優(yōu)點(diǎn)也是顯而易見(jiàn)的, 就是非常容易進(jìn)行擴(kuò)展。本節(jié)引用了這里的例子,并對(duì)其進(jìn)行了修改。裝飾模式要把裝飾模式說(shuō)清楚明白,不是件容易的事情。也許讀者知道Java IO中的幾個(gè)類(lèi)是典型的裝飾模式的應(yīng)用,但是讀
29、者不一定清楚其中的關(guān)系,也許看完就忘了,希 望看完這節(jié)后,讀者可以對(duì)其有更深的感悟。首先,我們先看一個(gè)簡(jiǎn)單的圖,看這個(gè)圖的時(shí)候,了解下層次結(jié)構(gòu)就可以了:我們來(lái)說(shuō)說(shuō)裝飾模式的出發(fā)點(diǎn),從圖中可以看到,接口Component其實(shí)已經(jīng)有了 ConcreteComponentA 和 ConcreteComponentB 兩個(gè)實(shí)現(xiàn)類(lèi)了,但是,如果我們 要增強(qiáng)這兩個(gè)實(shí)現(xiàn)類(lèi)的話(huà),我們就可以采用裝飾模式,用具體的裝飾器來(lái) 裝飾實(shí) 現(xiàn)類(lèi),以達(dá)到增強(qiáng)的目的。從名字來(lái)簡(jiǎn)單解釋下裝飾器。既然說(shuō)是裝飾,那么往往就是添加小功能這種,而且,我們要滿(mǎn)足可以添加多個(gè)小功能。最簡(jiǎn)單的,代理模式就可以實(shí)現(xiàn)功能的增強(qiáng),但是代理不容易實(shí)
30、現(xiàn)多個(gè)功能的 增強(qiáng),當(dāng)然你可以說(shuō)用代理包裝代理的方式,但是那樣的話(huà)代碼就復(fù)雜了。首先明白一些簡(jiǎn)單的概念,從圖中我們看到,所有的具體裝飾者們 ConcreteDecorator_都可以作為Component來(lái)使用,因?yàn)樗鼈兌紝?shí)現(xiàn)了 Component中的所有接口。它們和 Component實(shí)現(xiàn)類(lèi)ConcreteComponent_的區(qū) 別是,它們只是裝飾者,起 裝飾作用,也就是即使它們看上去牛逼轟轟,但怵 們都只是在具體的實(shí)現(xiàn)中 加了層皮來(lái)裝飾 而已。注意這段話(huà)中混雜在各個(gè)名詞中的Component和Decorator ,別搞混了。卜面來(lái)看看一個(gè)例子,先把裝飾模式弄清楚,然后再介紹下java i
31、o中的裝飾模式的應(yīng)用。最近大街上流行起來(lái)了 快樂(lè)檸檬",我們把快樂(lè)檸檬的飲料分為三類(lèi):紅茶、綠茶、 咖啡,在這三大類(lèi)的基礎(chǔ)上,又增加了許多的口味,什么金桔檸檬紅茶、金桔檸檬 珍珠綠茶、芒果紅茶、芒果綠茶、芒果珍珠紅茶、烤珍珠紅茶、烤珍珠芒果綠茶、 椰香胚芽咖啡、焦糖可可咖啡等等,每家店都有很長(zhǎng)的菜單,但是仔細(xì)看下,其實(shí)原料也沒(méi)幾樣,但是可以搭配出很多組合,如果顧客需要,很多沒(méi)出現(xiàn)在菜單中的 飲料他們也是可以做的。在這個(gè)例子中,紅茶、綠茶、咖啡是最基礎(chǔ)的飲料,其他的像金桔檸檬、芒果、珍 珠、椰果、焦糖等都屬于裝飾用的。當(dāng)然,在開(kāi)發(fā)中,我們確實(shí)可以像門(mén)店一樣,開(kāi)發(fā)這些類(lèi): LemonBl
32、ackTea、LemonGreenTea、MangoBlackTea、MangoLemonGreenTea但是,很快我們就發(fā)現(xiàn),這樣子干肯定是不行的,這會(huì) 導(dǎo)致我們需要組合出所有的可能,而且如果客人需要在紅茶中加雙份檸檬怎么辦? 三份檸檬怎么辦?萬(wàn)一有個(gè)變態(tài)要四份檸檬,所以這種做法是給自己找加班的。不說(shuō)廢話(huà)了,上代碼。首先,定義飲料抽象基類(lèi):public abstract class Beverage /返回描述public abstract String getDescription();/返回價(jià)格public abstract double cost();然后是三個(gè)基礎(chǔ)飲料實(shí)現(xiàn)類(lèi),紅茶、綠
33、茶和咖啡:public class BlackTea extends Beverage public String getDescription() return "紅茶";public double cost() return 10;public class GreenTea extends Beverage public String getDescription() return "綠茶";public double cost() return 11;./ 咖啡省略定義調(diào)料,也就是裝飾者的基類(lèi),此類(lèi)必須繼承自Beverage:/調(diào)料public a
34、bstract class Condiment extends Beverage 然后我們來(lái)定義檸檬、芒果等具體的調(diào)料,它們屬于裝飾者,毫無(wú)疑問(wèn),這些調(diào)料 肯定都需要繼承Condiment類(lèi):public class Lemon extends Condiment private Beverage bevarage;/這里很關(guān)鍵,需要傳入具體的飲料,如需要傳入沒(méi)有被裝飾的紅茶或綠茶,/當(dāng)然也可以傳入已經(jīng)裝飾好的芒果綠茶,這樣可以做芒果檸檬綠茶public Lemon(Beverage bevarage) this.bevarage = bevarage;public String getDes
35、cription() / 裝飾return bevarage.getDescription() + "public double cost() /裝飾return beverage.cost() + 2; /public class Mango extends Condiment private Beverage bevarage;public Mango(Beverage bevarage) this.bevarage = bevarage;public String getDescription() return bevarage.getDescription() + "
36、;public double cost() return beverage.cost() + 3; /./給每一種調(diào)料都加一個(gè)類(lèi)加檸檬”;加檸檬需要2元加芒果"加芒果需要3元看客戶(hù)端調(diào)用:public static void main(String args) /首先,我們需要一個(gè)基礎(chǔ)飲料,紅茶、綠茶或咖啡Beverage beverage = new GreenTea();/開(kāi)始裝飾beverage = new Lemon(beverage); /先加一份檸檬beverage = new Mongo(beverage); /再加一份芒果System.out.println(beve
37、rage.getDescription() + "價(jià)格:¥ " + beverage.cost();/" 綠茶,加檸檬,加芒果價(jià)格:¥ 16" 如果我們需要芒果珍珠雙份檸檬紅茶:Beverage beverage = new Mongo(new Pearl(new Lemon(new Lemon(new BlackTe a();是不是很變態(tài)?看看下圖可能會(huì)清晰一些:具體裝飾類(lèi)具體裝飾類(lèi)到這里,大家應(yīng)該已經(jīng)清楚裝飾模式了吧。下面,我們?cè)賮?lái)說(shuō)說(shuō)java IO中的裝飾模式??聪聢DInputStream派生出來(lái)的部分Java 10中的裝飾模3
38、InputStreamByleAraylfipulStreHni我們知道Inputstream代表了輸入流,具體的輸入來(lái)源可以是文件(FileInputStream )、管道(PipedInputStream )、數(shù)組(ByteArrayInputStream ) 等,這些就像前面奶茶的例子中的紅茶、綠茶,屬于基礎(chǔ)輸入流。FilterInputStream承接了裝飾模式的關(guān)鍵節(jié)點(diǎn),其實(shí)現(xiàn)類(lèi)是一系列裝飾器,比如 BufferedInputStream代表用緩沖來(lái)裝飾,也就使得輸入流具有了緩沖的功能, LineNumberInputStream代表用行號(hào)來(lái)裝飾,在操作的時(shí)候就可以取得行號(hào)了, Da
39、taInputStream的裝飾,使得我們可以從輸入流轉(zhuǎn)換為java中的基本類(lèi)型值。當(dāng)然,在java IO中,如果我們使用裝飾器的話(huà),就不太適合面向接口編程了,如:InputStream inputStream = new LineNumberInputStream(new BufferedInputSt ream(new FileInputStream("");這樣的結(jié)果是,InputStream還是不具有讀取行號(hào)的功能,因?yàn)樽x取行號(hào)的方法定 義在 LineNumberInputStream 類(lèi)中。我們應(yīng)該像下面這樣使用:DataInputStream is = new
40、DataInputStream(new BufferedInputStream(new FileInputStream("");所以說(shuō)嘛,要找到純的嚴(yán)格符合設(shè)計(jì)模式的代碼還是比較難的。門(mén)面模式門(mén)面模式(也叫外觀模式,F(xiàn)acade Pattern)在許多源碼中有使用,比如 slf4j就可 以理解為是門(mén)面模式的應(yīng)用。這是一個(gè)簡(jiǎn)單的設(shè)計(jì)模式,我們直接上代碼再說(shuō)吧。首先,我們定義一個(gè)接口:public interface Shape void draw();)定義幾個(gè)實(shí)現(xiàn)類(lèi):public class Circle implements Shape Overridepublic vo
41、id draw() System.out.println("Circle:draw()");public class Rectangle implements Shape Overridepublic void draw() System.out.println("Rectangle:draw()");客戶(hù)端調(diào)用:public static void main(String args) /畫(huà)一個(gè)圓形Shape circle = new Circle();circle.draw();/畫(huà)一個(gè)長(zhǎng)方形Shape rectangle = new Rectangl
42、e();rectangle.draw();)以上是我們常寫(xiě)的代碼,我們需要畫(huà)圓就要先實(shí)例化圓,畫(huà)長(zhǎng)方形就需要先實(shí)例化 一個(gè)長(zhǎng)方形,然后再調(diào)用相應(yīng)的 draw()方法。下面,我們看看怎么用門(mén)面模式來(lái)讓客戶(hù)端調(diào)用更加友好一些。我們先定義一個(gè)門(mén)面:public class ShapeMaker private Shape circle;private Shape rectangle;private Shape square;public ShapeMaker() circle = new Circle();rectangle = new Rectangle(); square = new Squar
43、e();/*/卜面定義一堆方法,具體應(yīng)該調(diào)用什么方法,由這個(gè)門(mén)面來(lái)決定public void drawCircle()circle.draw();)public void drawRectangle()rectangle.draw();)public void drawSquare()square.draw();)看看現(xiàn)在客戶(hù)端怎么調(diào)用:public static void main(String args) ShapeMaker shapeMaker = new ShapeMaker();/客戶(hù)端調(diào)用現(xiàn)在更加清晰了shapeMaker.drawCircle();shapeMaker.drawRectangle();shapeMaker.d
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 冀教版一年級(jí)下冊(cè)數(shù)學(xué)教學(xué)計(jì)劃(含進(jìn)度表)
- 人教版九年級(jí)下冊(cè)數(shù)學(xué)教學(xué)計(jì)劃(及進(jìn)度表)
- 2025年湖北省中考英語(yǔ)模擬試卷(附答案)
- 2025年第十屆安全生產(chǎn)知識(shí)競(jìng)賽經(jīng)典題庫(kù)及答案(共六套)
- 農(nóng)村小吃店開(kāi)業(yè)致詞簡(jiǎn)短
- 高新科技研發(fā)居間存款合同
- 航空票務(wù)居間服務(wù)合同
- 建筑柴油供應(yīng)居間協(xié)議樣本
- 城市公共交通運(yùn)營(yíng)合同
- 停車(chē)場(chǎng)智能門(mén)禁管理系統(tǒng)
- (一模)哈三中2025屆高三第一次模擬考試 語(yǔ)文試題(含答案)
- 西安市城鎮(zhèn)基本醫(yī)療保險(xiǎn)特殊藥品治療(備案計(jì)劃)申請(qǐng)表【模板】
- JJG 700-2016氣相色譜儀
- GB/T 26939-2011種羊鑒定術(shù)語(yǔ)、項(xiàng)目與符號(hào)
- 可編輯的中國(guó)地圖
- 《TV背光中光學(xué)膜片介紹及常見(jiàn)光學(xué)問(wèn)題分析》復(fù)習(xí)課件
- 手衛(wèi)生考核評(píng)分標(biāo)準(zhǔn)
- 部編版語(yǔ)文二年級(jí)下冊(cè)生字表(注音)
- 四級(jí)消防設(shè)施操作員(監(jiān)控)考核題庫(kù)與答案
- 《我在長(zhǎng)大》-完整版PPT
- 人身?yè)p害與疾病因果關(guān)系判定指南
評(píng)論
0/150
提交評(píng)論