JAVA設計模式之【代理模式】一(靜態代理)
代理模式
代理模式是物件的結構模式,給一個物件提供一個代理物件,由代理物件控制對原物件的引用。我們可以通過操作代理物件實現對原物件的呼叫。
本文主要講述靜態代理,jdk動態代理,cglib動態代理三種。
代理的種類
- 遠端(Remote)代理:
為一個位於不同的地址空間的物件提供一個局域代表物件。這個不同的空間地址可以是在本機器中,也可以是在另一臺機器中。
- 虛擬代理:
根據需要建立一個資源消耗較大的物件,使得此物件在真正需要時才會被建立。
- Copy-on-Write 代理:
虛擬代理的一種,把複製拖延到只有在客戶端需要時,才真正採取行動。
- 保護代理:
控制對一個物件的訪問,如果需要,可以給不同的使用者踢動不同級別的使用許可權。
- Cache代理:
為某一個目標操作的結果提供臨時的儲存空間,以便多個客戶端可以共享這些結果。
- 防火牆代理:
保護目標,不讓惡意使用者接近。
- 同步化代理:
使幾個使用者能否同時使用一個物件而沒有給衝突。
- 智慧引用代理:
當一個物件被引用時,提供一些額外的操作,比如講物件的呼叫次數記錄下來。
代理模式的結構(思想)
代理模式所涉及的角色有:
- 抽象主題角色
- 真實主題角色
- 代理主題角色
1. 抽象主題角色
聲明瞭真實主題和代理主題之間的共同介面,代理主題
/**
* 抽象主題
* @author wuqiong
*
*/
public abstract class Subject {
public abstract void request();
}
2. 真實主題角色
定義了真實物件,也就是我們想讓代理物件操作的實際物件,它實現了抽象介面。
/**
* 真實主題
* @author wuqiong
*
*/
public class RealSubject extends Subject {
@Override
public void request() {
System.out.println("真實主題request方法執行");
}
}
3. 代理主題角色
代理主題角色同樣實現抽象類,同時內部包含了對真實主題的引用,從而可以在任何時候操作真實主題物件。代理角色通常在客戶端真正呼叫的真實主題之前或者之後,執行某個操作,而不是單獨的將呼叫傳遞給真實的角色。
/**
* 代理主題角色
* @author wuqiong
*
*/
public class ProxySubject extends Subject {
private RealSubject realSubject = new RealSubject();
@Override
public void request() {
preRequest();
realSubject.request();
afterRequest();
}
public void preRequest() {
System.out.println("request方法執行之前執行");
}
public void afterRequest() {
System.out.println("request方法執行之後執行");
}
}
測試執行結果:
public class ProxyTest {
public static void main(String[] args) {
ProxySubject ps = new ProxySubject();
ps.request();
}
}
列印結果
request方法執行之前執行
真實主題request方法執行
request方法執行之後執行
從上面的代理主題類的程式碼可以看出代理模式是怎麼樣工作的,首先,代理模式並不改變主題的介面,因為模式的用意並不是讓客戶端感受到代理的存在。其次,代理使用委派將客戶端的呼叫委派給真實的主題物件,代理主題在其中起到了傳遞請求的左右。最後,代理主題在傳遞請求之前和之後都可以執行特定的程式碼,而不是單純的執行請求。
代理模式的時序
當客戶端向代理主題發出請求時,代理主題接受到請求的同事,先執行一個preRequest()操作,然後才把請求傳遞給真實的主題。真實主題執行之後,又執行了afterRequest()方法,才將控制返回給客戶端。
簡而言之,就是代理模式將一箇中間層插入到了客戶端和主題角色之間,從而提供了許多靈活性。