一、靜態(tài)代理實(shí)現(xiàn)
按照代理模式的類圖:

代理模式類圖
靜態(tài)代理,代理類在編譯時(shí)生成;即,需要編碼代理類。
從實(shí)現(xiàn)上來看,靜態(tài)代理類不具備真實(shí)主題類處理真正請(qǐng)求的能力,因此需要將請(qǐng)求交給真實(shí)主題對(duì)象處理;為了獲取真是主題類的能力,代理類可以繼承真實(shí)主題類,或者組合真實(shí)主題對(duì)象。
設(shè)計(jì)原則
多用組合,少用繼承
即使通過繼承可以滿足需求,但是由于繼承不如組合靈活,采用組合會(huì)更好一些。
由此,靜態(tài)代理的實(shí)現(xiàn)步驟一般為(主題接口Subject, 真實(shí)主題對(duì)象類RealSubject一般都是存在的):
- 創(chuàng)建代理類,實(shí)現(xiàn)主題接口Subject;
- 代理類持有真實(shí)主題對(duì)象類的引用;
- 代理類實(shí)現(xiàn)主題接口Subject的方法,并委托給引用的真實(shí)主題對(duì)象類處理。
二、實(shí)例:計(jì)算耗時(shí)操作
要為一項(xiàng)耗時(shí)操作計(jì)時(shí),最直觀的做法是在耗時(shí)操作前后打印當(dāng)前時(shí)間,但是這樣的代碼不利于維護(hù)。使用代理模式,從設(shè)計(jì)上
- 首先需要為計(jì)時(shí)操作創(chuàng)建接口,即主題接口
- 實(shí)現(xiàn)主題接口,即真實(shí)主題類提供真正的耗時(shí)操作
- 代理類組合真是主題類實(shí)例,實(shí)現(xiàn)主題接口
- 客戶端使用代理類完成耗時(shí)任務(wù)請(qǐng)求
實(shí)現(xiàn)類圖如下

靜態(tài)代理實(shí)現(xiàn)
完整代碼見附錄。
refer to
[1] java靜態(tài)代理和動(dòng)態(tài)代理
附錄
靜態(tài)代理實(shí)現(xiàn)
// Subject主題接口
public interface Subject {
void doTask();
}
// 真是主題類,真正處理請(qǐng)求的類
public class RealSubject implements Subject {
@Override
public void doTask() {
try {
Thread.sleep(10000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 攔截對(duì)真實(shí)主題對(duì)象訪問,代理類
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();
}
}