1. 程式人生 > >JAVA設計模式之【代理模式】一(靜態代理)

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()方法,才將控制返回給客戶端。
簡而言之,就是代理模式將一箇中間層插入到了客戶端和主題角色之間,從而提供了許多靈活性。