設計模式學習--------12.代理模式學習
場景:
? ? ?福爾摩斯一直想送禮物給花生,可是羞於直接贈送,於是想到讓房東太太去幫忙送禮物.編程怎樣實現呢?
定義:
? ? ? 為其它對象提供一種代理以控制對這個對象的訪問。
角色:
Proxy:代理對象.有下列功能:
實現與詳細的目標對象一樣的接口,這樣就能夠使用代理來取代詳細的目標對象。
持有一個詳細目標對象的引用,能夠在須要時調用詳細的目標對象。
能夠控制對目標對象的訪問,並能夠負責創建和刪除它。
package com.kris.study;
public class Proxy implements Subject {
private RealSubject realSubject = null;
public Proxy(RealSubject realSubject){
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("代理之前做一些操作。。。。。。");
realSubject.request();
System.out.println("代理之後做一些操作。 。
。。。
。");
}
}
Subject:目標接口
package com.kris.study;
public interface Subject {
public void request();
}
RealSubject:詳細的目標對象,被代理的對象
package com.kris.study;
public class RealSubject implements Subject {
@Override
public void request() {
//運行詳細的功能處理
}
}
以下用代理模式實現場景。
package com.kris.study; public interface SendGift { public void send(); }
package com.kris.study;
public class Holmes implements SendGift {
@Override
public void send() {
System.out.println("送禮物給花生---來自福爾摩斯");
}
}
package com.kris.study; public class FangDongTaiTai implements SendGift { private Holmes holmes = null; public FangDongTaiTai(Holmes holmes){ this.holmes = holmes; } @Override public void send() { System.out.println("親愛的花生,老福讓我給你帶個東西"); holmes.send(); } }
package com.kris.study;
public class Client {
public static void main(String[] args) {
Holmes holmes = new Holmes();
SendGift sendGift = new FangDongTaiTai(holmes);
sendGift.send();
}
}
上面講的都是靜態代理,JAVA中提供了一套動態代理的機制,更加靈活。眼下JAVA的動態代理僅僅支持接口,若要實現類的代理,能夠使用cglib.
步驟:
1. ?創建一個實現接口InvocationHandler的類,它必須實現invoke方法。
2. ?創建被代理的類以及接口
3. ?通過Proxy的靜態方法new ProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h)
創建一個代理,這個代理不管運行什麽方法都會轉到Handler中的invoke方法去調用.
4. ?通過代理調用方法
上面第一步中的invoke方法參數說明
pubilc Object invoke(Object obj,Method method,Object[] args)
obj:代理類
method:被代理的方法
args:方法的參數
動態代理實現場景:
上面的SendGift接口和Holmes類都沒變化,如今把房東太太的實現變更為實現InvocationHandler
package com.kris.study;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class FangDongTaiTai implements InvocationHandler {
private SendGift holmes = null;
public SendGift bindObject(Holmes holmes){
this.holmes = holmes;
SendGift sendProxy = (SendGift) Proxy.newProxyInstance(holmes.getClass().getClassLoader(),
holmes.getClass().getInterfaces(), this);
return sendProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("親愛的花生,這是大福給你的");
return method.invoke(holmes, args);
}
}
package com.kris.study;
public class Client {
public static void main(String[] args) {
Holmes holmes = new Holmes();
FangDongTaiTai giftSendHandler = new FangDongTaiTai();
SendGift proxy = giftSendHandler.bindObject(holmes);
proxy.send();
}
}
思考:
代理模式的本質:控制對象的訪問
特點:
遠程代理:Android中的Binder機制就是通過代理實現,本地通過一個代理對象去調用遠程Service的方法。
虛代理:比方載入數據庫中全部人員數據,頁面上僅僅顯示人員名字,點擊名字能夠查看人員詳細信息,這樣先用代理對象載入全部人員的名字和ID.當真正須要看其它詳細信息時,用代理對象再次去數據庫載入全部人員數據。
保護代理:對目標對象的訪問進行權限的管控,在代理對象中須要滿足某種條件才幹調用目標對象的方法。
智能指引:在代理方法的前後運行一些附加的業務邏輯。AOP切面。
何時使用代理:
1.須要為一個對象在不同的地址空間提供局部代表的時候,能夠使用遠程代理
2.須要創建開銷非常大的對象時。能夠使用虛代理。
3.須要控制對原始對象的訪問的時候。能夠使用保護代理
4.須要在訪問對象運行一些附加操作的時候。能夠使用智能指引代理
設計模式學習--------12.代理模式學習