Java 代理模式和裝飾者模式的區別

裝飾模式:以對客戶端透明的方式擴展對象的功能,是繼承關係的一個替代方案;
代理模式:給一個對象提供一個代理對象,並有代理對象來控制對原有對象的引用;程序員


裝飾模式應該爲所裝飾的對象加強功能;代理模式對代理的對象施加控制,並不提供對象自己的加強功能設計模式

兩者的實現機制確實是同樣的,能夠看到他們的實例代碼重複是不少的。但就語義上說,這二者的功能是相反的,模式的一個重要做用是簡化其餘程序員對你程序的理解,學習

你在一個地方寫裝飾,你們就知道這是在增長功能,你寫代理,你們就知道是在限制,this

雖然代碼極可能相同,但若是你都叫他們裝飾,別人會很迷惑的。翻譯

--------------------------------------------------------------設計

學習AOP時,教材上面都說使用的是動態代理,但是在印象中代理模式一直都是控制訪問什麼的,怎麼又動態增長行爲了,動態增長行爲不是裝飾器模式嗎?因而 找了不少資料,想弄清楚這二者之間到底有什麼區別。結果發現這一篇英文文章講的很清晰,就翻譯一下,供參考。       代理

        首先,讓咱們先看一下下面的這兩個UML類圖,他們分別描述了裝飾器模式和代理模式的基本實現。component

                    

                     

        這兩個圖可能使咱們產生困惑。這兩個設計模式看起來很像。對裝飾器模式來講,裝飾者(decorator)和被裝飾者(decoratee)都實現同一個 接口。對代理模式來講,代理類(proxy class)和真實處理的類(real class)都實現同一個接口。此外,不論咱們使用哪個模式,均可以很容易地在真實對象的方法前面或者後面加上自定義的方法。對象

        然而,實際上,在裝飾器模式和代理模式之間仍是有不少差異的。裝飾器模式關注於在一個對象上動態的添加方法,然而代理模式關注於控制對對象的訪問。換句話 說,用代理模式,代理類(proxy class)能夠對它的客戶隱藏一個對象的具體信息。所以,當使用代理模式的時候,咱們經常在一個代理類中建立一個對象的實例。而且,當咱們使用裝飾器模 式的時候,咱們一般的作法是將原始對象做爲一個參數傳給裝飾者的構造器。blog

        咱們能夠用另一句話來總結這些差異:使用代理模式,代理和真實對象之間的的關係一般在編譯時就已經肯定了,而裝飾者可以在運行時遞歸地被構造。    

代理模式:

//代理模式
public class Proxy implements Subject{

       private Subject subject;
       public Proxy(){
             //關係在編譯時肯定
            subject = new RealSubject();
       }
       public void doAction(){
             ….
             subject.doAction();
             ….
       }
}

 

//代理的客戶
public class Client{
        public static void main(String[] args){
             //客戶不知道代理委託了另外一個對象
             Subject subject = new Proxy();
             …
        }
}

裝飾模式:

//裝飾器模式
public class Decorator implements Component{
        private Component component;
        public Decorator(Component component){
            this.component = component
        }
       public void operation(){
            ….
            component.operation();
            ….
       }
}

 

//裝飾器的客戶
public class Client{
        public static void main(String[] args){
            //客戶指定了裝飾者須要裝飾的是哪個類
            Component component = new Decorator(new ConcreteComponent());
            …
        }
}
相關文章
相關標籤/搜索