23種設計模式(6)-裝飾者模式

 

定義:php

    在沒必要改變原類文件和原類使用的繼承的狀況下,動態地擴展一個對象的功能。ide

    它是經過建立一個包裝對象,也就是用裝飾來包裹真實的對象來實現。測試

 

角色:this

    抽象構件角色(Project):給出一個接口,以規範準備接收附加責任的對象。spa

    具體構件角色(Employe):定義一個將要接收附加責任的類。調試

    裝飾角色(Manager):持有一個構件對象的實例,並定義一個與抽象構件接口一致的接口。code

    具體裝飾角色(ManagerA、ManagerB):負責給構件對象「貼上」附加的責任。對象

 

示例:繼承

公共接口:接口

 

public interface Person {  
    void eat();  
}

被裝飾對象:

 

public class OldPerson implements Person {  
    @Override  
    public void eat() {  
        System.out.println("吃飯");  
    }  
}

 

裝飾對象:

 

public class NewPerson implements Person {  
    private OldPerson p;  

    NewPerson(OldPerson p) {  
        this.p = p;  
    }  

    @Override  
    public void eat() {  
        System.out.println("生火");  
        System.out.println("作飯");  
        p.eat();  
        System.out.println("刷碗");   
    }  
}

 

測試:

 

public class PersonDemo {  
    public static void main(String[] args) {  
        OldPerson old = new OldPerson();  
        //old.eat(); 
        NewPerson np = new NewPerson(old);  
        np.eat();  
    }  
}

        經過例子能夠看到,沒有改變原來的OldPerson類,同時也沒有定義他的子類而實現了Person的擴展,這就是裝飾者模式的做用。

 

優勢:

        1,使用裝飾者模式比使用繼承更加靈活,由於它選擇經過一種動態的方式來擴展一個對象的功能,在運行時能夠選擇不一樣的裝飾器,從而實現不一樣的行爲。

        2,經過使用不一樣的具體裝飾類以及這些裝飾類的排列組合,能夠創造出不少不一樣行爲的組合。能夠使用多個具體裝飾類來裝飾同一對象,獲得功能更爲強大的對象。

        3,具體構件類與具體裝飾類能夠獨立變化,他能是低耦合的。用戶能夠根據須要來增長新的具體構件類和具體裝飾類,在使用時再對其進行各類組合,原有代碼無須改變,符合「開閉原則」。

 

缺點:

        1,會產生不少的小對象,增長了系統的複雜性

        2,這種比繼承更加靈活機動的特性,也同時意味着裝飾模式比繼承更加易於出錯,排錯也很困難,對於屢次裝飾的對象,調試時尋找錯誤可能須要逐級排查,較爲煩瑣。

 

裝飾者與適配者模式的區別:

   1,適配器模式主要用來兼容那些不能在一塊兒工做的類,使他們轉化爲能夠兼容目標接口,雖然也能夠實現和裝飾者同樣的增長新職責,但目的不在此。

        裝飾者模式主要是給被裝飾者增長新職責的。

   2,適配器模式是用新接口來調用原接口,原接口對新系統是不可見或者說不可用的。

        裝飾者模式原封不動的使用原接口,系統對裝飾的對象也經過原接口來完成使用。

   3,適配器是知道被適配者的詳細狀況的(就是那個類或那個接口)。

        裝飾者只知道其接口是什麼,至於其具體類型(是基類仍是其餘派生類)只有在運行期間才知道。

 

裝飾者和繼承的區別:

繼承:

  優勢:代碼結構清晰,並且實現簡單

  缺點:對於每個的須要加強的類都要建立具體的子類來幫助其加強,這樣會致使繼承體系過於龐大。

裝飾者:

  優勢:內部能夠經過多態技術對多個須要加強的類進行加強

       缺點:須要內部經過多態技術維護須要加強的類的實例。進而使得代碼稍微複雜。

 

使用場景:

        1,須要擴展一個類的功能,或給一個類添加附加職責。

        2,須要動態的給一個對象添加功能,這些功能可能不明確或者暫時的,能夠隨時很方便的動態撤銷掉。

        3,須要增長由一些基本功能的排列組合而產生的很是大量的功能,從而使繼承關係變的不現實。

        4. 當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。

 

Java知音公衆號推送一些Java必備的知識,讓您在閒暇之餘鞏固一下本身的知識體系 ,擴充一下本身的知識面。快利用瑣碎時間給本身充watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相關文章
相關標籤/搜索