設計模式之禪(3)-裝飾者模式


更多關於設計模式的文章請點擊設計模式之禪(0)-目錄頁


裝飾者模式是23種設計模式之中的一種常用的設計模式,英文叫Decorator Pattern。裝飾模式是在不必改變原類文件和使用繼承的情況下,動態地擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。

一、裝飾者模式的特點

1、 裝飾對象和真實對象有相同的接口。這樣客戶端對象就能以和真實對象相同的方式和裝飾對象交互。
2、 裝飾對象包含一個真實對象的引用(reference。
3、 裝飾對象接受所有來自客戶端的請求。它把這些請求轉發給真實的對象。
4、 裝飾對象可以在轉發這些請求以前或以後增加一些附加功能。這樣就確保了在運行時,不用修改給定對象的結構就可以在外部增加附加的功能。在面向對象的設計中,通常是通過繼承來實現對給定類的功能擴展。

二、裝飾者模式的使用情景

1、 需要擴展一個類的功能,或給一個類添加附加職責。
2、需要動態的給一個對象添加功能,這些功能可以再動態的撤銷。
3、要增加由一些基本功能的排列組合而產生的非常大量的功能,從而使繼承關係變的不現實。
4、 當不能採用生成子類的方法進行擴充時。一種情況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增長。另一種情況可能是因爲類定義被隱藏,或類定義不能用於生成子類。

三、裝飾者模式的一般關係圖

在這裏插入圖片描述

在這裏插入圖片描述

四、裝飾者模式的代碼實現

在這裏插入圖片描述

  • Animal超類
/**
 * @Description:    Animal超類
 * @CreateDate: Created in 2018/11/25 11:03
 * @Author: <a href="https://blog.csdn.net/pbrlovejava">arong</a>
 */
public abstract class Animal {
    private String description;

    public abstract String getDescription();


    public void setDescription(String description) {
        this.description = description;
    }
}
  • Dog子類
/**
 * @Description: Dog extends Animal
 * @CreateDate: Created in 2018/11/25 11:09
 * @Author: <a href="https://blog.csdn.net/pbrlovejava">arong</a>
 */
public class Dog extends Animal {

    @Override
    public String getDescription() {
        setDescription("dog");
        return "dog";
    }
}
  • Bigger -Animal的包裝類
/**
 * @Description: Bigger是一個裝飾者
 * @CreateDate: Created in 2018/11/25 11:12
 * @Author: <a href="https://blog.csdn.net/pbrlovejava">arong</a>
 */
public class Bigger extends Animal{
    private Animal animal;

    public Bigger(Animal animal){
        this.animal = animal;
    }
    @Override
    public String getDescription() {
        return animal.getDescription()+"Bigger";
    }
}
  • 使用Bigger包裝類去包裝Dog子類
/**
 * @Description: 測試裝飾者模式
 * @CreateDate: Created in 2018/11/25 11:21
 * @Author: <a href="https://blog.csdn.net/pbrlovejava">arong</a>
 */
public class TestDecoratorPattern {

    @Test
    public void BiggerDecorateDog(){
        Animal dog = new Dog();
        //使用裝飾者裝飾前
        String wrapBefore = dog.getDescription();
        System.out.println("使用裝飾者裝飾前"+wrapBefore);
        //創建裝飾者Bigger用以包裝Dog
        Animal biggerDog = new Bigger(dog);
        //使用裝飾者裝飾後
        String wrapAfter = biggerDog.getDescription();
        System.out.println("使用裝飾者裝飾後"+wrapAfter);
    }
}

在這裏插入圖片描述

五、裝飾者模式使用的設計原則

1、多組合,少繼承
每一個裝飾者都需要組合一個Animal,這樣才能在包裝時得到原先被裝飾者的屬性和方法等,支持在構造方法中動態地擴展。

2、類應設計的對擴展開放,對修改關閉。

六、I/O流-典型的裝飾者模式

Java標準庫中的I/O流庫是使用裝飾者模式實現的:
在這裏插入圖片描述
它們的方法和屬性繼承自超類InputStream,所以,它們在使用方面幾乎大同小異,但是會有少許的增強方法。

在這裏插入圖片描述

七、裝飾者模式的弊端

  1. 這種比繼承更加靈活機動的特性,也同時意味着更加多的複雜性。
  2. 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程序變得很複雜。
  3. 裝飾模式是針對抽象組件(Component)類型編程。但是,如果你要針對具體組件編程時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component接口,增加新的公開的行爲,實現“半透明”的裝飾者模式。在實際項目中要做出最佳選擇。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章