一、裝飾模式概述
Decorator模式動態的給一個對象添加一些額外的職責。就添加功能來說,Decorator模式相比生成子類更為靈活。
以下情況適合使用Decorator模式:1、在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責;2、處理那些可以撤銷的職責;3、當不能產用生成子類的方法進行擴充時。
Decorator模式的類圖如下:
參與者:
Component:裝飾器模式中公共方法的類,處於裝飾器模式結構圖的頂層。
ConcreateComponent:裝飾器模式中具體被裝飾的類,IO包中的媒體流就是此種對象。
Decorator:裝飾器模式中的核心對象,所有具體裝飾器對象的父類,完成裝飾器的部分職能。該類可以只做一些簡單的包裹被裝飾的對象,也可以還包含對Component中方法的實現……他有一個鮮明的特點:繼承至Component,同時包含一個Component作為其成員變量。裝飾器模式動機中的動態地增加功能是在這裡實現的。
ConcreteDecoratorA和ConcreteDecoratorB是兩個具體的裝飾器對象,他們完成具體的裝飾功能。裝飾功能的實現是通過調用被裝飾對象對應的方法,加上裝飾對象自身的方法。這是裝飾器模式動機中的添加額外功能的關鍵。
注意,ConcreteDecoratorA和ConcreteDecoratorB的方法不完全一樣,這就是一般設計模式中談及裝飾器模式的“透明裝飾器”和“不透明裝飾器”。“透明裝飾器”就是整個Decorator的結構中所有的類都保持同樣的“接口”(這裡是共同方法的意思),這是一種極其理想的狀況。現實中絕大多數裝飾器都是“不透明裝飾器”,他們的“接口”在某些子類中得到增強。
二 、JDK中的裝飾器模式
在jdk中使用了裝飾器模式的是IO類庫。說實話,我並不是很喜歡java的IO類庫,因為在我使用Java的這一年多時間裡,我快被Java I/O類庫中那些功能相似,卻又絕對可稱得上龐雜的類搞得要發瘋了,只是想簡單的輸入輸出而已,卻要創建出3、4個類,比之C/C++復雜多了!
但是學了裝飾器模式之後,我終於搞明白為什麼JDK中要設計出這麼多功能相似的幾十個類出來,因為java I/O庫就使用了裝飾器模式,它比繼承模式更靈活,可擴展性更強。
java I/O庫類層次結構圖如下:
三 、關於裝飾器模式的思考
關於裝飾器模式至少有兩個主要優點和兩個缺點:1、比靜態繼承更靈活;2、避免在層次結構高層的類有太多的特征;3、Decorator和Component不一樣;4、有許多小對象。
這幾個特點在java I/O庫中表現的十分明顯!