理解並使用設計模式,能夠培養我們良好的物件導向編程習慣,同時在實際應用中,可以如魚得水,享受遊刃有餘的樂趣。
代理模式是比較有用途的一種模式,而且變種較多,應用場合覆蓋從小結構到整個系統的大結構,Proxy是代理的意思,我們也許有Proxy 伺服器等概念,代理概念可以解釋為:在出發點到目的地之間有一道中介層,意為代理。
代理模式的定義是:為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下,一個對象不適合或者不能直接引用另一個對象,而代理對象可以在用戶端和目標對象之間起到中介的作用。它可以為委派物件預先處理訊息,過濾訊息並轉寄訊息,以及進行訊息被委派物件執行後的後續處理,
或許有人會疑惑,為什麼不直接用呢,非得需要代理呢?我們看下面一個情境:
"商女不知亡國恨;一天到晚打Dota;舉頭望明月,低頭打Dota;洛陽親友如相問,就說我在打Dota;少壯不努力,老大打Dota;垂死病中驚坐起,今天還沒打Dota;生當作人傑,死亦打Dota;人生自古誰無死,來生繼續打Dota。。。"
這就是當今大學男生宿舍的概況。小蔡是XX大學的電腦系大四學生,上面說的“歌謠”,也是他的大學生涯的真是寫照。人稱“小菜”,技術也真是菜到了家,不過卻是“越挫越勇”,一天到晚打Dota,吃飯也不離開宿舍,一個電話搞定。這不,又來了:
啪的一拍鍵盤,“呼,終於贏了,差點讓對方給辦了,幸好對方的幽鬼被女朋友給拽走了。。。”,一看時間,“呀,都11點40了,不知不覺中又該吃飯啦”,嘀咕了一聲,在被子裡摸索了半天,抄起“王牌手機”諾基亞1100,撥通了那個無比熟悉的號碼。。。
“喂,飯(範)哥,我是蔡哥呀。。。。嗯,對,對,還是Dota套餐,好,快點呀,掛了!”
範哥也是大四學生,從大一就開始做“代理訂餐”的業務,已經有不小的“業績”和很好的口碑了,人稱“飯哥”。
10分鐘,飯到,5分鐘飯畢,然後菜哥又開始他偉大的Dota生涯了。。。。
情景結束。
在上面的情景中,食堂賣飯,範哥也賣飯,不過範哥賣的卻是從食堂倒手而來的,小菜委託範哥去買,就相當於去食堂買飯了。這就是一個典型的代理模式。我們用代碼和圖說明一下:
源碼:SellMeal.java 售飯介面
package com.bjpowernode.pattern.bookmeal;/** * 售飯介面 * @author Longxuan * */public interface SellMeal {/** * 售飯方法 */public void sellRice();}
Restaurant.java 餐廳類
package com.bjpowernode.pattern.bookmeal;/** * 餐廳 * @author Longxuan * */public class Restaurant implements SellMeal {/** * 餐廳售飯 */@Overridepublic void sellRice() {System.out.println("1份米飯,2份菜(涼+熱),1份雞蛋湯。");}}
SellMealProxy.java 訂餐代理類
package com.bjpowernode.pattern.bookmeal;/** * 訂餐代理類,飯哥 * @author Longxuan * */public class SellMealProxy implements SellMeal {private SellMeal sellMeal = null;public SellMealProxy(SellMeal sellMeal){this.sellMeal = sellMeal;System.out.println("您好,我是訂餐的範哥:");}/** * 訂餐售飯 */@Overridepublic void sellRice() {System.out.println("這是您的Dota套餐:");sellMeal.sellRice();System.out.println("歡迎您的惠顧。");}}
DotaGG.java 用戶端類,訂飯的Dota兄
package com.bjpowernode.pattern.bookmeal;/** * 用戶端類,訂飯的Dota兄 * @author Longxuan * */public class dotaGG {public static void main(String[] args){//找代理食堂訂飯的範哥SellMealProxy FanGG = new SellMealProxy(new Restaurant());//向範哥訂飯FanGG.sellRice();}}
運行結果:
從源碼中可以看到,用戶端通過代理訪問到目標對象,從而避免了與目標對象的直接接觸。所以Dota兄小菜不用自己去買飯,就可以吃到食堂的飯菜了,同時節省了時間。而範哥賺了點money,雖然不多,但是貴在“薄利多銷”,而且在每次送餐,都有在不經意間打出廣告。客戶多自然利潤多,也就有了其存在的價值。
也就是說,我們不是非得直接讓原對象去訪問目標對象,有時候那樣並不好,不合適,或者現實生活中不可能出現那種情況。所以我們需要一個代理類,去協助我們完成這些操作,而且這些代理還可以對訊息預先處理和後繼處理。這就是代理存在的意義。
如果你細心些,會發現一個代理類服務一個介面。即有100個不同的目標對象,則需要用到100個介面和對應的代理類,這也是靜態代理的弊端。如何解決這個弊端呢?請期待我的下一篇博文。