摘要:感受設計演變過程中所蘊含的大智慧,體會樂與怒的程序人生中值得回味的一幕幕。本文轉自大話設計模式第七章之代理模式!
本文轉載于: http://blog.csdn.net/monkey_d_meng/article/details/5689877
7.1為別人做嫁衣
“小菜,今天見這個叫嬌嬌的美女見得如何呀?”大鳥一回家來就問小菜。
“唉,別提了,人家是有男朋友的。”小菜無精打采地答道。
“有男朋友了啊,這倒是我沒料到,那為什么還找你幫忙修電腦?”
“她男友叫戴勵,在北京讀大學呢,他們高中就開始談戀愛了。”小菜說,“而且她還告訴了我一件比較有趣的事。”
“哦,是什么?”
“是這樣的,我們在吃飯的時候,我就問她,怎么不找男友幫修電腦。她說男友在北京讀書,所以沒辦法幫助修。我心里一想,‘你在上海怎么男友會在北京’,正想問他們是怎么認識的,她卻接著問我想不想知道他男友追她的事。哈,這不正是我所希望的嗎,于是我就跟著她開始了美好的回憶。”
“又不是你談戀愛,說得這么肉麻,還‘美好的回憶’。她回憶什么了?”
“當時她是這么說的:‘那是在我高中二年級時的一天下午……’”
“嬌嬌同學,這是有人送你的禮物。”一個男生手拿著一個芭比娃娃送到她的面前。
“戴勵同學.這是什么意思?”嬌嬌望著同班的這個男生,感覺很奇怪。
“是這樣的,我的好朋友,隔壁三班的卓賈易同學,請我代他送你這個禮物的。”戴勵有些臉紅。
“為什么要送我禮物,我不認識他呀。”
“他說……他說……他說想和你交個朋友。”戴勵臉更紅了,右手抓后腦勺,說話吞吞吐吐。
“不用這樣,我不需要禮物的。”嬌嬌顯然想拒絕,
“別別別,他是我最好的朋友,他請我代他送禮物給你,也是下了很大決心的,你看在我之前時常幫你輔導數學習題的面子上,就接受一下吧。”戴勵有些著急。
“那好吧,今天我對解析幾何的橢圓那里還是不太憧,你再給我講講。”嬌嬌提出條件后接過禮物。
“沒問題,我們到教室去講吧。”戴勵松了口氣。
幾天后
“嬌嬌,這是卓賈易送你的花。”
“嬌嬌,這是卓賈易送你的巧克力。”
“我不要他送的東西了,我也不想和他交朋友。我愿意……我愿意和你做朋友!”嬌嬌終于忍不住了,
直接表白。
“啊,……我不是在做夢吧……”戴勵喜從天降,不敢相信。
“呆子!”嬌嬌微笑地罵道。
戴勵用手抓了抓頭發說,“其實我也喜歡你。不過,……不過,那我該如何向卓賈易交待昵?”
從此戴勵和嬌嬌開始戀愛了。畢業后,戴勵考上了北京XX大學,而嬌嬌讀了上海的大專。
“喂,醒醒,還在陶醉呀。這個戴勵根本就是一個大騙子,哪有什么卓賈易,這是他自己想泡MM找的借口。”大鳥不屑一顧。
“我當時也是這么想的,但她說是真的有這個人,后來那個卓賈易氣死了,差點和戴勵翻臉。”小菜肯定地說。
“那就不能怪戴勵了,卓賈易就是為別人在做嫁衣,所以自己苦惱也是活該,誰叫他不自己主動,找人代理談戀愛,神經病呀,”
“是呀,都怪他自己。為別人做嫁衣的滋味不好受哦。”
“這里又可以談到一個設計模式了。”
“你不說我也知道是哪一個,代理模式對吧?”
“哈,說得沒錯。小菜真是越來越聰明。”
“去去去,口是心非的東西,代理模式又是怎么講的?”
“你先試著寫如果卓賈易直接追嬌嬌,應該如何做?”
7.2沒有代理的代碼
十分鐘后,小菜寫出了第一份代碼。
結構圖
- //被追求者類?? ??
- public ? class ?SchoolGirl????
- {????
- ???? public ?String???name;????
- ????
- ???? public ?String?getName()????
- ????{????
- ???????? return ? this .name;????
- ????}????
- ????
- ???? public ? void ?setName(String?name)????
- ????{????
- ???????? this .name?=?name;????
- ????}????
- }????
- //追求者類?? ??
- public ? class ?Pursuit????
- {????
- ????SchoolGirl??mm;????
- ????
- ???? public ?Pursuit(SchoolGirl?mm)????
- ????{????
- ???????? this .mm?=?mm;????
- ????}????
- ????
- ???? public ? void ?giveDolls()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你洋娃娃" );????
- ????}????
- ????
- ???? public ? void ?giveFlowers()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你鮮花" );????
- ????}????
- ????
- ???? public ? void ?giveChocolate()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你巧克力" );????
- ????}????
- }????
- //客戶端代碼?? ??
- public ? class ?Main????
- {????
- ???? public ? static ? void ?main(String[]?args)????
- ????{????
- ????????SchoolGirl?jiaojiao?=? new ?SchoolGirl();????
- ????????jiaojiao.setName( "李嬌嬌" );????
- ????
- ????????Pursuit?zhuojiayi?=? new ?Pursuit(jiaojiao);????
- ????
- ????????zhuojiayi.giveDolls();????
- ????????zhuojiayi.giveFlowers();????
- ????????zhuojiayi.giveChocolate();????
- ????}????
- }????
?
“我了個擦,嬌嬌并不認識卓賈易,這樣寫的話不就等于卓賈易自己去送東西了嘛。”
“是哇,這如何處理來著?”
“而且,你丫把戴勵給弄哪去了?”
“哈,對的對的,戴勵就是代理啊。”
7.3只有代理的代碼
十分鐘后。
結構圖
?
- //被追求者類?? ??
- public ? class ?SchoolGirl????
- {????
- ???? public ?String???name;????
- ????
- ???? public ?String?getName()????
- ????{????
- ???????? return ? this .name;????
- ????}????
- ????
- ???? public ? void ?setName(String?name)????
- ????{????
- ???????? this .name?=?name;????
- ????}????
- }????
- //代理類?? ??
- public ? class ?Proxy????
- {????
- ????SchoolGirl??mm;????
- ????
- ???? public ?Proxy(SchoolGirl?mm)????
- ????{????
- ???????? this .mm?=?mm;????
- ????}????
- ????
- ???? public ? void ?giveDolls()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你洋娃娃" );????
- ????}????
- ????
- ???? public ? void ?giveFlowers()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你鮮花" );????
- ????}????
- ????
- ???? public ? void ?giveChocolate()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你巧克力" );????
- ????}????
- }????
- //客戶端代碼?? ??
- public ? class ?Main????
- {????
- ???? public ? static ? void ?main(String[]?args)????
- ????{????
- ????????SchoolGirl?jiaojiao?=? new ?SchoolGirl();????
- ????????jiaojiao.setName( "李嬌嬌" );????
- ????
- ????????Proxy?daili?=? new ?Proxy(jiaojiao);????
- ????
- ????????daili.giveDolls();????
- ????????daili.giveFlowers();????
- ????????daili.giveChocolate();????
- ????}????
- }????
“我了個擦,你丫寫的是個啥?”
“這又有什么問題,為什么出錯的總是我。”
“你把Pursuit(追求者)換成了Proxy(代理),把卓賈易換成戴勵。這就使得這個禮物變成是戴勵送的,而你剛才還肯定地說,卓賈易這個人是存在的,禮物是他買的,你這怎么能正確呢?”
“哦,我明白了,我這樣寫把Pursuit追求者給忽略了,事實上應該Pursuit追求者通過Proxy代理送給SchoolGirl被追求者禮物,這才是合理的。那我應該如何辦呢? SchoolGirl被追求者送的禮物是Pursuit追求者買的,實質是還是追求者Pursuit送的,只是通過Proxy代理了。”
“很好,既然兩者都有相同的方法,那就意味著他們都怎樣?”
“哦,你的意思是他們都實現了同樣的接口?我想,我可以寫出代碼來了。”
“小菜開竅了。”
7.4符合實際的代碼
十分鐘后。小菜第三份代碼。
結構圖
- //代理接口?? ??
- public ? interface ?GiveGift????
- {????
- ???? void ?giveDolls();????
- ????
- ???? void ?giveFlowers();????
- ????
- ???? void ?giveChocolate();????
- }????
- //追求者類?? ??
- public ? class ?Pursuit? implements ?GiveGift????
- {????
- ????SchoolGirl??mm;????
- ????
- ???? public ?Pursuit(SchoolGirl?mm)????
- ????{????
- ???????? this .mm?=?mm;????
- ????}????
- ????
- ???? public ? void ?giveDolls()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你洋娃娃" );????
- ????}????
- ????
- ???? public ? void ?giveFlowers()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你鮮花" );????
- ????}????
- ????
- ???? public ? void ?giveChocolate()????
- ????{????
- ????????System.out.println(mm.name?+? "?送你巧克力" );????
- ????}????
- }????
- //代理類?? ??
- public ? class ?Proxy? implements ?GiveGift????
- {????
- ????Pursuit?gg;????
- ????
- ???? public ?Proxy(SchoolGirl?mm)????
- ????{????
- ????????gg?=? new ?Pursuit(mm);????
- ????}????
- ????
- ???? public ? void ?giveChocolate()????
- ????{????
- ????????gg.giveChocolate();????
- ????}????
- ????
- ???? public ? void ?giveDolls()????
- ????{????
- ????????gg.giveDolls();????
- ????}????
- ????
- ???? public ? void ?giveFlowers()????
- ????{????
- ????????gg.giveFlowers();????
- ????}????
- }????
- //客戶端代碼?? ??
- public ? class ?Main????
- {????
- ???? public ? static ? void ?main(String[]?args)????
- ????{????
- ????????SchoolGirl?jiaojiao?=? new ?SchoolGirl();????
- ????????jiaojiao.setName( "李嬌嬌" );????
- ????
- ????????Proxy?daili?=? new ?Proxy(jiaojiao);????
- ????????daili.giveDolls();????
- ????????daili.giveFlowers();????
- ????????daili.giveChocolate();????
- ????}????
- }????
?
“這下好了,嬌嬌不認識追求她的人,但卻可以通過代理人得到禮物。效果也達到了。”
“這就是代理模式。好了,我們來看看GoF對代理模式是如何描述的。”
7.5代理模式
代理模式(Proxy),為其他對象提供一種代理以控制對這個對象的訪問。
代理模式(Proxy)結構圖
- //Subject類,定義了RealSubject和Proxy的共用接口,這樣就在任何使用RealSubject的地方都可以使用Proxy。?? ??
- public ? interface ?Subject????
- {????
- ???? public ? void ?request();????
- }????
- //RealSubject類,定義Proxy所代表的真實實體。?? ??
- public ? class ?RealSubject? implements ?Subject????
- {????
- ???? public ? void ?request()????
- ????{????
- ????????System.out.println( "真實的請求" );????
- ????}????
- }????
- //Proxy類,保存一個引用使用代理可以訪問實體,并提供一個與Subject的接口相同的接口,這樣的代理可以用替代實體。?? ??
- public ? class ?Proxy? implements ?Subject????
- {????
- ????RealSubject?realSubject;????
- ????
- ???? public ? void ?request()????
- ????{????
- ???????? if ?( null ?==?realSubject)????
- ????????{????
- ????????????realSubject?=? new ?RealSubject();????
- ????????}????
- ????????realSubject.request();????
- ????}????
- }????
- //客戶端代碼?? ??
- public ? class ?Main????
- {????
- ???? public ? static ? void ?main(String[]?args)????
- ????{????
- ????????Proxy?proxy?=? new ?Proxy();????
- ????????proxy.request();????
- ????}????
- }????
7.6代理模式應用
“那代理模式一般應用于什么場合呢?”
“一般來說可以分為以下幾種:第一,遠程代理,也就是為一個對象在不同的地址空間提供局部代表。這樣可以隱藏一個對象存在于不同地址空間的事實。”
“這么抽象的說,你能不能舉個具體點的例子說明一下。”
“其實你一定用過的,WebService在.NET中的應用是怎樣做的?”
“哦,我明白什么叫遠程代理了,當我在應用程序的項目中加入一個Web引用,引用一個WebService,此時會在項目中生成一個WebReference的文件夾和一些文件,其實它們就是代理,這就使得客戶端程序調用代理就可以解決遠程訪問的問題。原來這就是代理模式的應用啊。”
“第二種應用是虛擬代理,是根據需要創建開銷很大的對象。通過它來存放實例化需要很長時間的真實對象。這樣就可以達到性能的最優化,比如說你打開一個很大的HTML網頁時,里面可能有很多的文字和圖片,但你還是可以很快地打開它,此時你所看到的所有文字,但圖片卻是一張一張地下載后,才能看到的。那些未打開的圖片框,就是通過虛擬代理來替代了真實的圖片,此時代理存儲了真實圖片的路徑和尺寸。”
“哦,原來瀏覽器當中是用代理模式來優化下載的啊。”
“第三種應用是安全代理,用來控制真實對象訪問時的權限。一般用于對象應該有不同的訪問權限的時候。第四種是智能指引,是指當調用真實對象時,代理處理另外一些事。如計算真實對象的引用次數,這樣當該對象沒有引用時,可以自動釋放它;或當第一次引用一個持久對象時,將它裝入內存;或在訪問一個實際對象前,檢查是否已經鎖定它,以確保其他對象不能改變它。它們都是通過代理在訪問一個對象時附加一些內務處理。”
“啊,原來代理可以做這么多的事情啊,我還以為它是一個很不常用的模式呢。”
“代理模式其實就是在訪問對象時引入一定程度的間接性,因為這種間接性,可以附加多種用途。”
“哦,明白,說白了,代理就是真實對象的代表。”
7.7秀才讓小六代其求婚
“好了,看會兒電視吧,好幾天沒看《武林外傳》了。”大鳥打開了電視,此時武林外傳正在播放第22集。
當播放到最后片段時,劇中,郭芙蓉對呂秀才惡狠狠地說:“呂秀才,是你讓小六向我求婚的吧?”
“造物弄人!”呂秀才慘慘地答道,“這只是一個玩笑。”
“哦! ……玩笑!”郭芙蓉冷笑地說,“我殺了你!”
秀才速奔出去,郭芙蓉口中叫著“你給我站住!”跟著跑了出去……
小菜和大鳥看到這里,轉頭相互看著對方,小菜說:“呂秀才讓燕小六代其向郭芙蓉求婚,這不就是…”,兩人異口同聲的說:“代一理一模一式!”
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
