我學設計模式 之 代理模式

sz_bdqn發表於2010-09-22

我學設計模式之代理模式

 

1.  簡介

代理模式是物件的結構模式。代理模式給一個物件提供了一個代理物件,並由代理物件控制物件的引用。

              所謂代理,就是一個人或一個機構代表另一個人或機構採取行動。

 

       如果使用代理模式的目的來劃分,代理有以下幾種:

n         遠端代理:為一個物件在不同的地址空間提供區域性代表。例如EJB

n         虛擬代理:更具需要開銷很大的物件。例如,當我們開啟一個網頁的時候,文字會很快顯示出來,但圖片會慢慢顯示出來,瀏覽器對圖片的處理就採用了代理模式。

n         Copy – on – Write代理:

n         保護代理:控制對原始物件的訪問。例如:利用代理來訪問一些受保護的資源,由代理完成鑑權工作。

n         Cache代理:

n         防火牆代理:

n         同步化代理:

n         智慧引用代理:

n         功能代理:完成某些功能的時候需要一些附加的工作,這時候可以利用代理來進行處理。

 

 

2.  代理模式的結構

代理模式所涉及的角色有:

抽象主題角色:宣告瞭真是主題和代理主題的共同介面,這樣一來在任何時候可以使用真實代理主題的地方都可以使用代理主題。

代理主題角色:代理主題角色內部含有真實主題的引用,從而可以在任何使用操作真實主題物件;代理主題角色提供一個與真實主題角色相同的介面,以便可以在任何時候可以替代真實主題;控制真實主題的引用,負責需要的時候建立真實主題物件(和刪除真實主題);代理主題角色通常在將客戶端呼叫遞給真實主題之前或之後,都要執行某個操作,而不是單純地呼叫傳遞給真實主題物件。

真實主題角色:定義了代理角色所代表的真實主題。

       這裡給出代理模式一個簡單的UML圖:

3.  代理模式的用法

這部門給出上面UML圖中的程式碼:

抽象主題原始碼:

package com.zsw.proxy;

 

abstract public class Subject {

   

    /**

     * 宣告一個抽象的請求方法

     */

    abstract public void request();

}

 

真實主題:

package com.zsw.proxy;

 

public class RealSubject extends Subject {

   

    /**

     * 宣告一個抽象的請求方法

     */

    public void request(){

       System.out.println("-------------真實主題-------------");

    }

}

 

 

代理主題:

package com.zsw.proxy;

public class ProxySubject extends Subject {

    private RealSubject realSubject;

    public ProxySubject(){     

    }

   

    /**

     * 宣告一個抽象的請求方法

     */

    public void request(){

       preRequest();

       if(realSubject == null){

           realSubject = new RealSubject();

       }

        realSubject.request();

       postRequest();

    }

   

    private void preRequest(){

       System.out.println("-------------請求前的操作-------------");

    }

   

    private void postRequest(){

       System.out.println("-------------請求後的操作-------------");

    }

}

 

 

客戶端:

package com.zsw.proxy;

public class Client {

    public static void main(String[] args) {

       Subject subject = new ProxySubject();

       subject.request();

    }

}

 

使用代理的顯著好處是,系統提供了向真實主題傳遞客戶請求的控制。代理主題可以在向真實主題傳遞客戶請求之前執行特定的操作,並決定是否將請求傳遞給真實主題;代理主題可以在向真實主題傳遞請求後執行另外的一些操作。

 

 

4.  代理模式的應用的場景

1)        Java中的反射與動態代理,Java語言通過在java.lang.reflect庫中提供下面三個類直接支援代理:ProxyInvocationHandlerMethod。如果以後在開發專案中,需要對那個方法呼叫前後執行一些其他的方法,可以考慮使用此模式,例如:事務的開啟與關閉。

2)        高老莊的故事,故事情節大家都熟悉在這就省略了….

悟空扮演並代替高三小姐,其中可以把高三小姐的神貌當做抽象角色,高三小姐本身是真實角色,孫悟空則是代理角色。其UML圖如下:

 

悟空代替高三小姐去會見豬八戒。這就是代理模式的運用,具體的講,這是保護代理模式的應用。只有代理物件認為合適的時候,才會將客戶端的請求傳遞給真實主題物件。

3)        比如要建立一個系統開銷很大的物件、或者被呼叫物件在遠端主機上、或目標物件功能還不足以滿足需求.

4)        Hibernate延遲載入所採用的設計模式,Hibernate關聯對映是的知識,當A實體和B實體之間存在關聯關係是,Hibernate模式啟動延遲載入,當系統載入A實體時,A實體關聯的B實體並沒有被載入出來,A實體所關聯的B實體全部都是代理物件----只有等到A實體正真需要訪問B實體時,系統才會去資料庫裡抓取B實體所對應的記錄,Hibernate的延遲載入充分體現了代理模式的優勢。當實體載入A實體時,也許只需要訪問A實體對應的記錄,根本不會訪問B實體對應的記錄。如果不採用代理模式,系統需要載入A實體時,同時載入A實體所有關聯實體,這是多麼大的系統開銷啊!,在這裡情況下,代理模式可以顯著的提高系統執行效能。

5)        Spring AOP代理的方法可以在執行目標物件的方法之前、之後插入一些通用的處理。代理模式可以為被代理物件新增一些額外的功能。

 

5.  代理模式的優缺點

1)        優點:

ü         提供系統執行的效能。

ü         可以為被代理物件新增一些額外的功能。

2).缺點

 

 

6.  參考資料

1)        Java 模式》

2)        《企業級Java開發與架構專業程式設計師在實戰中的蛻變》

待續.........

相關文章