裝飾模式:以對(duì)客戶端透明的方式擴(kuò)展對(duì)象的功能展辞,是繼承關(guān)系的一個(gè)替代方案奥邮;
代理模式:給一個(gè)對(duì)象提供一個(gè)代理對(duì)象,并有代理對(duì)象來控制對(duì)原有對(duì)象的引用罗珍;
裝飾模式應(yīng)該為所裝飾的對(duì)象增強(qiáng)功能洽腺;代理模式對(duì)代理的對(duì)象施加控制,并不提供對(duì)象本身的增強(qiáng)功能
二者的實(shí)現(xiàn)機(jī)制確實(shí)是一樣的覆旱,可以看到他們的實(shí)例代碼重復(fù)是很多的蘸朋。但就語義上說,這兩者的功能是相反的扣唱,模式的一個(gè)重要作用是簡化其他程序員對(duì)你程序的理解藕坯,
首先团南,讓我們先看一下下面的這兩個(gè)UML類圖,他們分別描述了裝飾器模式和代理模式的基本實(shí)現(xiàn)堕担。
這兩個(gè)圖可能使我們產(chǎn)生困惑已慢。這兩個(gè)設(shè)計(jì)模式看起來很像。對(duì)裝飾器模式來說霹购,裝飾者(decorator)和被裝飾者(decoratee)都實(shí)現(xiàn)同一個(gè) 接口佑惠。對(duì)代理模式來說,代理類(proxy class)和真實(shí)處理的類(real class)都實(shí)現(xiàn)同一個(gè)接口齐疙。此外膜楷,不論我們使用哪一個(gè)模式,都可以很容易地在真實(shí)對(duì)象的方法前面或者后面加上自定義的方法贞奋。
然而赌厅,實(shí)際上,在裝飾器模式和代理模式之間還是有很多差別的轿塔。裝飾器模式關(guān)注于在一個(gè)對(duì)象上動(dòng)態(tài)的添加方法特愿,然而代理模式關(guān)注于控制對(duì)對(duì)象的訪問。換句話 說勾缭,用代理模式揍障,代理類(proxy class)可以對(duì)它的客戶隱藏一個(gè)對(duì)象的具體信息。因此俩由,當(dāng)使用代理模式的時(shí)候毒嫡,我們常常在一個(gè)代理類中創(chuàng)建一個(gè)對(duì)象的實(shí)例。并且幻梯,當(dāng)我們使用裝飾器模 式的時(shí)候兜畸,我們通常的做法是將原始對(duì)象作為一個(gè)參數(shù)傳給裝飾者的構(gòu)造器。
我們可以用另外一句話來總結(jié)這些差別:使用代理模式碘梢,代理和真實(shí)對(duì)象之間的的關(guān)系通常在編譯時(shí)就已經(jīng)確定了咬摇,而裝飾者能夠在運(yùn)行時(shí)遞歸地被構(gòu)造。
代理模式:
//代理模式
public class Proxy implements Subject{
private Subject subject;
public Proxy(){
//關(guān)系在編譯時(shí)確定
subject = new RealSubject();
}
public void doAction(){
….
subject.doAction();
….
}
}
//代理的客戶
public class Client{
public static void main(String[] args){
//客戶不知道代理委托了另一個(gè)對(duì)象
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){
//客戶指定了裝飾者需要裝飾的是哪一個(gè)類
Component component = new Decorator(new ConcreteComponent());
…
}
}