? ? ?理解并使用設計模式,能夠培養我們良好的面向對象編程習慣,同時在實際應用中,可以如魚得水,享受游刃有余的樂趣。
? ? ?代理模式是比較有用途的一種模式,而且變種較多,應用場合覆蓋從小結構到整個系統的大結構,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 {
/**
* 餐廳售飯
*/
@Override
public 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("您好,我是訂餐的范哥:");
}
/**
* 訂餐售飯
*/
@Override
public 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個接口和對應的代理類,這也是靜態代理的弊端。如何解決這個弊端呢?請期待我的[下一篇博文](http://blog.csdn.net/xiaoxian8023/article/details/9274359)。
? ??