一、靜態(tài)代理實現
按照代理模式的類圖:
代理模式類圖
靜態(tài)代理,代理類在編譯時生成;即,需要編碼代理類。
從實現上來看,靜態(tài)代理類不具備真實主題類處理真正請求的能力,因此需要將請求交給真實主題對象處理;為了獲取真是主題類的能力,代理類可以繼承真實主題類,或者組合真實主題對象。
設計原則
多用組合,少用繼承
即使通過繼承可以滿足需求,但是由于繼承不如組合靈活,采用組合會更好一些。
由此,靜態(tài)代理的實現步驟一般為(主題接口Subject, 真實主題對象類RealSubject一般都是存在的):
- 創(chuàng)建代理類,實現主題接口Subject;
- 代理類持有真實主題對象類的引用;
- 代理類實現主題接口Subject的方法,并委托給引用的真實主題對象類處理。
二、實例:計算耗時操作
要為一項耗時操作計時,最直觀的做法是在耗時操作前后打印當前時間,但是這樣的代碼不利于維護。使用代理模式,從設計上
- 首先需要為計時操作創(chuàng)建接口,即主題接口
- 實現主題接口,即真實主題類提供真正的耗時操作
- 代理類組合真是主題類實例,實現主題接口
- 客戶端使用代理類完成耗時任務請求
實現類圖如下
靜態(tài)代理實現
完整代碼見附錄。
refer to
附錄
靜態(tài)代理實現
// Subject主題接口
public interface Subject {
void doTask();
}
// 真是主題類,真正處理請求的類
public class RealSubject implements Subject {
@Override
public void doTask() {
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 攔截對真實主題對象訪問,代理類
public class Proxy implements Subject {
private Subject realSubject;
public Proxy(Subject realSubject) {
this.realSubject = realSubject;
}
@Override
public void doTask() {
long start = System.currentTimeMillis();
System.out.println("task begins");
realSubject.doTask();
System.out.println("task ends, duration: \t" + (-start + System.currentTimeMillis()) / 1000 + "s");
}
}
// 客戶端代理
public class Client {
public static void main(String[] args) {
Subject realSubject = new RealSubject();
Subject proxy = new Proxy(realSubject);
proxy.doTask();
}
}