代理模式(Proxy)
阿新 • • 發佈:2018-11-15
提高 時間 創建 -c 所表 文件 return int embed
1、概念
代理模式為其他對象提供一個代理以控制對這個對象的訪問,屬於結構性模式。從代碼的角度來分,代理可以分為兩種:一種是靜態代理,另一種是動態代理。
靜態代理就是在程序運行前就已經存在代理類的字節碼文件,代理類和委托類的關系在運行前就確定了。
動態代理類的源碼是在程序運行期間根據反射等機制動態的生成,所以不存在代理類的字節碼文件。代理類和委托類的關系是在程序運行時確定。
2、模式結構
- Subject(抽象主題類):接口或者抽象類,聲明真實主題與代理的共同接口方法。
- RealSubject(真實主題類):也叫做被代理類或被委托類,定義了代理所表示的真實對象,負責具體業務邏輯的執行,客戶端可以通過代理類間接的調用真實主題類的方法。
- Proxy(代理類):也叫委托類,持有對真實主題類的引用,在其所實現的接口方法中調用真實主題類中相應的接口方法執行。
3、使用場景
- 當一個對象不能或者不想直接訪問另一個對象時,可以通過一個代理對象來間接訪問
- 被訪問的對象不想暴露全部內容時,可以通過代理去掉不想被訪問的內容
- 一個消耗資源較少的對象來代表一個消耗資源較多的對象,從而降低系統開銷、縮短運行時間時
4、優缺點
優點:
- 協調調用者和被調用者,降低了系統的耦合度
- 代理對象作為客戶端和目標對象之間的中介,起到了保護目標對象的作用
- 以一個小對象代理一個大對象,達到優化系統提高運行速度的目的
缺點:
- 調用者和真實主題之間增加了代理對象,因此可能會造成請求的處理速度變慢。
- 實現代理模式需要額外的工作,從而增加了系統實現的復雜度
5、實例
靜態實例
public interface IUserDao {
int save();
}
public class UserDao implements IUserDao {
@Override
public int save() {
return 0;
}
}
public class UserDaoProxy implements IUserDao { //接收保存目標對象 private IUserDao target; public UserDaoProxy(IUserDao target) { this.target = target; } @Override public int save() { return target.save(); } }
動態實例:
還是使用靜態代理的IUserDao和UserDao 類,改造UserDaoProxy 類,利用java的newProxyInstance動態生成實例。
public class UserDaoProxy {
//維護一個目標對象
private Object target;
public UserDaoProxy(Object target) {
this.target = target;
}
//給目標對象生成代理對象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//運用反射執行目標對象方法
Object returnValue = method.invoke(target, args);
return returnValue;
}
}
);
}
}
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
System.out.println(target.getClass());
// 給目標對象,創建代理對象
IUserDao proxy = (IUserDao) new UserDaoProxy(target).getProxyInstance();
proxy.save();
}
代理模式(Proxy)