本章是對設(shè)計模式之禪一書中代理模式一章的總結(jié)與整理。
1.定義
為其它對象提供一種代理以控制對這個對象的訪問余佛。不好理解席函,設(shè)計模式的每種類型的定義第一遍都不太好讀懂的,這句話翻譯成大白話就是:你要想訪問我捌刮,對不起,找我代理吧舒岸。用另外的話說就是:你要訪問一個對象绅作,對不起,通過它的代理去訪問它吧蛾派,人家不想和你直接打交道俄认。最簡單的實例就是:你要去拜訪一個明星,是不是得先去找人家的經(jīng)紀(jì)人呢洪乍。代理就是這么個意思眯杏,這是根本,這個是宗旨壳澳。通用類圖如下:
2.擴(kuò)展與類型
第一類:普通代理
書中將普通代理分為了兩個大類岂贩,一個是透明代理,一個是普通代理巷波。
透明代理:就是用戶不用設(shè)置代理萎津,可以直接訪問真實的(比如代理服務(wù)器)
普通代理:要求是客戶只能訪問代理角色,而不能訪問真實的角色抹镊,這個是最好理解的锉屈。一個真實的示例就是:懶人買余額寶,由余額寶去買基金垮耳,余額寶就是代理角色颈渊,而你實際買的應(yīng)該是一些基金,只不過是通過余額寶購買的。
第二類:強(qiáng)制代理
這個比較變態(tài)儡炼,你根本不知道代理是誰妓湘,只知道真實角色是誰查蓉,你必須通過真實的對象獲取它的代理類乌询,然后通過代理類去訪問真實角色,如果不是真實角色給你的代理你也無法訪問豌研,挺變態(tài)的妹田。
示例是這樣的:你的一個朋友現(xiàn)在是一名很牛X的歌手,你要去訪問他鹃共,然后給他打電話問他什么時候有空鬼佣,然后他告訴你“這樣吧,你找我代理吧霜浴,讓他告訴你”晶衷,你說變態(tài)不變態(tài)。
第三類:虛擬代理
它的意思就是說:在需要的時候才初始化主題對象阴孟。我不太明白它的具體用途是什么晌纫?
第四類:動態(tài)代理
動態(tài)代理是在實現(xiàn)階段(就是編碼階段)不用關(guān)心代理是誰,而在運(yùn)行階段才指定代理哪一個對象永丝,反過來說锹漱,自己寫代理類的方式就是靜態(tài)代理。
我們來舉一個示例慕嚷,在帝都很多人都有過找房子的經(jīng)歷哥牍,以此為例。首先得有人喝检,定義一個接口租房子,它有兩個方法:找房子嗅辣,簽合同。
public interface IRent {
public void searchHouse();
public void contractHouse();
}
實現(xiàn)這個方法挠说,其代碼如下:
public class Renter implements IRent {
String name="";
public Renter(String _name){
this.name=_name;
}
@Override
public void searchHouse() {
System.out.println(this.name+"正在找房子");
}
@Override
public void contractHouse() {
System.out.println(this.name+"正在簽合同");
}
}
接下來實現(xiàn)代理類澡谭,其代碼如下:
public class RentProxy implements InvocationHandler {
//被代理的對象
Object target=null;
public RentProxy(Object _object){
this.target=_object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//執(zhí)行被代理的方法
//在執(zhí)行這個被代理的方法前后可以執(zhí)行你想執(zhí)行的操作,比如打印日志纺涤,判斷Session等
return method.invoke(this.target,args);
}
}
動態(tài)代理請務(wù)必實現(xiàn)InvocationHandler接口译暂,這個接口只有一個方法,在這個方法中調(diào)用被代理類的實際方法撩炊。這一點(diǎn)很不好理解外永,可以在此先記住這個,以后慢慢理解拧咳。
再看場景類的具體實現(xiàn):
public class Client {
public static void main(String[] strings){
//定義房客
IRent iRent=new Renter("張三");
//定義handler
InvocationHandler invocationHandler=new RentProxy(iRent);
//動態(tài)產(chǎn)生一個代理
IRent proxy= (IRent)Proxy.newProxyInstance(iRent.getClass().getClassLoader(),new Class[]{IRent.class},invocationHandler);
proxy.searchHouse();
proxy.contractHouse();
}
}
場景類分四步走:
定義房客
定義Handler
使用jdk 提供的Proxy類動態(tài)產(chǎn)生一個代理類
通過產(chǎn)生的動態(tài)代理類伯顶,去執(zhí)行相應(yīng)的方法
對比以上的場景類,基本就是按照這個思路來的。
以上這些就是代理模式的相關(guān)內(nèi)容祭衩。