怎麼理解裝飾器模式
- 裝飾器模式(Decorator Pattern)允許向一個現有的對象添加新的功能,同時又不改變其結構。這種類型的設計模式屬於結構型模式,它是作爲現有的類的一個包裝。
- 這種模式創建了一個裝飾類,用來包裝原有的類,並在保持類方法簽名完整性的前提下,提供了額外的功能。
- 其實我們可以這樣理解裝飾器模式, 就拿自己舉例子,你把自己裸體的樣子,想象成被裝飾的對象。你的鞋子,你的寸衣,你的外套,你的手錶,你的帽子 等等,都是你的裝飾物,你和這些裝飾物,是裝飾和被裝飾的關係
舉個簡單例子
首先,我們發現,不管是裸體的人,還是你的鞋子、帽子,都有展示的功能,我們稱之爲show 方法。
我們定義一個接口,它具有展示的功能,也就是show()
public interface AbstractPerson {
//具有展示的功能
void show() ;
}
定義一個裸體的自己了,Me 類
public class Me implements AbstractPerson {
@Override
public void show() {
System.out.println( "什麼都沒穿,我展示的是裸體");
}
}
下面該定義,鞋子,帽子,手錶等 裝飾物,等等先別急,我們應該先定義一個鞋子,帽子,手錶的抽象父類 AbstractClothes
public abstract class AbstractClothes implements AbstractPerson {
AbstractPerson abstractPerson ;
public AbstractClothes( AbstractPerson abstractPerson ){
this.abstractPerson = abstractPerson ;
}
@Override
public void show() {
abstractPerson.show();
}
}
下面開始定義,帽子裝飾物 Hat 類, 繼承 AbstractClothes 類
public class Hat extends AbstractClothes {
public Hat(AbstractPerson abstractPerson) {
super(abstractPerson);
}
@Override
public void show() {
super.show();
say();
}
public void say(){
System.out.println( "我展示一個帽子");
}
}
定義鞋子裝飾類 Shoes , 繼承 AbstractClothes 類
public class Shoes extends AbstractClothes {
public Shoes(AbstractPerson abstractPerson) {
super(abstractPerson);
}
@Override
public void show() {
super.show();
say();
}
public void say(){
System.out.println( "我展示一雙鞋子");
}
}
test
public class Test {
public static void main(String[] args) {
//創建被裝飾者
Me me = new Me() ;
//裸體的人被裝飾了帽子 ,具有了展示帽子的能力
Hat hat = new Hat( me ) ;
// 帶了帽子的人被裝飾了鞋子,具有了展示鞋子的本領
Shoes shoes = new Shoes( hat ) ;
shoes.show();
}
}
•什麼都沒穿,我展示的是裸體
•我展示一個帽子
•我展示一雙鞋子
UML類圖
- Component抽象構件角色:真實對象和裝飾對象有相同的接口。這樣,客戶端對象就能夠以與真實對象相同的方式同裝飾對象交互。
- ConcreteCompoent具體構建角色(真實對象):定義一個將要接收附加責任的類。
- Decorator裝飾角色:持有一個抽象構件的引用。裝飾對象接受所有客戶端的請求,並把這些請求轉發給真實的對象。這樣,就能在真實對象調用前後增加新的功能。
- ConcreteDecorate具體裝飾角色:負責給構件對象增加新的功能。
- Component抽象構件角色:io流中的InputStream,OutputStream,Reader,Writer
- ConcreteComponent具體構件角色:io流中的FileInputStream,FileOutputStream
- Decorate裝飾角色:持有抽象構件的引用,FilterInputStream,FilterOutputStream
- ConcreteDecorate具體裝飾角色:負責給構件對象添加新的責任,BufferedInputStream,BufferedOutputStream等
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(path), "utf-8"));
裝飾器模式的優點和缺點
優點 :擴展對象功能,比繼承靈活,不會導致類個數急劇增加。可以對一個對象進行多次裝飾,創造出不同行爲的組合,得到功能更加強大的對象。具體構 件 類和具體裝飾類可以獨立變化,用戶可以根據需要自己增加新的 具體構件子類和具體裝飾子類。
缺點:產生很多小對象。大量小的對象佔據內存,一定程度上影響性能。裝飾模式易出錯,調試排查比較麻煩。
場景
如果沒有裝飾器模式,還是我們上面的例子,我們就要生成穿鞋子的人的類,帶帽子的人的類,同時穿鞋子和戴帽子的人的類。。。假設有4種裝飾物和被裝飾對象就有15種組合,如果類更多呢,就會使得類爆炸,這時候裝飾器模式的優點就體現出來了,需要一個接口,一個個抽象類和5個實現類。
參考資料:http://blog.csdn.net/zhaoyanjun6/article/details/56488020