代理模式
在代理模式中,有兩個對象參與處理同一請求,接收的請求由代理對象委託給真實對象處理。代理對象在應用中與目標對象之間起到一箇中介橋樑的作用
特點
1.代理者和被代理者一般擁有相同的接口或者抽象類
2.在代理對象中,有被代理對象的引用
設計原則:
1.延遲加載,提高系統效率
2.單一職責原則
代理模式使用代理對象將真實對象分離開,可以在代理對象中做一些權限判斷,一些邏輯處理。具體動作執行放在真實對象中執行,如此,將代理對象和真實對象的功能職責單一化,分離了不同處理行爲,降低了功能模塊這幾件的耦合度。也方便後期維護,在代理模式中,代理對象與真實對象實現了相同的接口,是面向抽象的編程,也符合設計模式的依賴倒置原則,即依賴抽象,而不依賴與具體實現類(此處代理類,被代理的引用是引用所實現的接口,而不是引用具體的被代理實現類)
使用場合:
1.遠程代理:爲一個對象在不同的地址空間提供局部代理(aidl就是遠程代理)
2.虛擬代理:若一個對象的創建非常耗時,可通過代理對象去調用,在真實對象創建前,範圍一個假的調用,等真實對戲那個創建號了。再返回一個真實對象的相應方法調用
3.保護代理:控制對原始對象的訪問
4.智能指引
動態代理
所謂Dynamic Proxy是這樣一種class:它是在運行時生成的class,在生成它時你必須提供一組interface給它,然後該class就宣稱它實現了這些 interface。你當然可以把該class的實例當作這些interface中的任何一個來用。當然啦,這個Dynamic
Proxy其實就是一個Proxy,它不會替你作實質性的工作,在生成它的實例時你必須提供一個handler,由它接管實際的工作。
Demo
1.實現類接口
public interface IuserManager {
public String test(String userId);
public String test1(String userId,String userName);
}
2.具體實現類public class UserManagerImplimplements IuserManager {
@Override
public String test(String userId) {
System.out.println("UserManagerImpl--》test-->>" + userId);
return"張三";
}
@Override
public String test1(String userId, String userName) {
// TODO Auto-generated method stub
returnnull;
}
}
3.動態代理類
//動態代理,都必須實現 InvocationHandler接口
public class BusinessHandlerimplements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object targetObject) {
this.targetObject = targetObject;
// Proxy.newProxyInstance三個參數
// 第一個參數定義代理類型的加載者
// 被代理對象的實現的接口列表
// 實現invocationHandler的對象
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("start-->" + method.getName());
for (int i = 0; i < args.length; i++) {
System.out.println("args-->"+args[i]);
}
Object ret = null;
try {
// 調用目標方法 targetObject method所在的類args爲method的參數
ret = method.invoke(targetObject, args);
System.out.println("success-->" + method.getName());
} catch (Exception ex) {
}
// TODO Auto-generated method stub
return ret;
}
}
4.測試BusinessHandler businessHandler = new BusinessHandler();
IuserManager usermanage = (IuserManager) businessHandler.newProxyInstance(new UserManagerImpl());
String name = usermanage.test("001");
System.out.println("Client.main() --- " + name);
測試結果
start-->test
args-->001
UserManagerImpl--》test-->>001
success-->test
Client.main() --- 張三