設計模式之禪(3)-裝飾者模式
阿新 • • 發佈:2018-11-29
文章目錄
更多關於設計模式的文章請點選:設計模式之禪(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,所以,它們在使用方面幾乎大同小異,但是會有少許的增強方法。
七、裝飾者模式的弊端
- 這種比繼承更加靈活機動的特性,也同時意味著更加多的複雜性。
- 裝飾模式會導致設計中出現許多小類,如果過度使用,會使程式變得很複雜。
- 裝飾模式是針對抽象元件(Component)型別程式設計。但是,如果你要針對具體元件程式設計時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component介面,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際專案中要做出最佳選擇。