Java程序員們應該對java.io對不會陌生,因為java.io包采用了裝飾器模式。
一、定義:
Decorator裝飾器,顧名思義,就是動態地給一個對象添加一些額外的職責,就好比為房子進行裝修一樣。因此,裝飾器模式具有如下的特征:
它必須具有一個裝飾的對象。
它必須擁有與被裝飾對象相同的接口。
它可以給被裝飾對象添加額外的功能。
用一句話總結就是:保持接口,增強性能。
裝飾器通過包裝一個裝飾對象來擴展其功能,而又不改變其接口,這實際上是基於對象的適配器模式的一種變種。它與對象的適配器模式的異同點如下。
相同點:都擁有一個目標對象。
不同點:適配器模式需要實現另外一個接口,而裝飾器模式必須實現該對象的接口。
二、 典型的裝飾器模式的圖:

三、相關實例:
1、 Sourcable接口定義了一個方法 operation() 。
- package pattern.decorator;
- public interface Sourcable {
- public void operation();
- }
2、 Source.java 是 Sourcable.java 的一個實現, operation() 方法的實現就是簡單的負責往控制台輸出一個字符串:
- package pattern.decorator;
- public class Source implements Sourcable {
- public void operation() {
- System.out.println("原始類的方法");
- }
- }
3、裝飾器類 Decorator1.java 采用了典型的對象適配器模式,它首先擁有一個 Sourcable 對象 source ,該對象通過構造函 數進行初始化。然后它實現了 Sourcable.java 接口,以期保持與 source 同樣的接口,並在重寫的operation() 方法中調用 source 的 operation() 函數,在調用前后可以實現自己的輸出,這就是裝飾器所擴展的功能。
- package pattern.decorator;
- public class Decorator1 implements Sourcable {
- private Sourcable sourcable;
- public Decorator1(Sourcable sourcable){
- super();
- this.sourcable=sourcable;
- }
- public void operation() {
- System.out.println("第1個裝飾器前");
- sourcable.operation();
- System.out.println("第1個裝飾器后");
- }
- }
裝飾器類Decorator2.java 是另一個裝飾器,不同的是它裝飾的內容不一樣,即輸出了不同的字符串。其源代碼如
- package pattern.decorator;
- public class Decorator2 implements Sourcable {
- private Sourcable sourcable;
- public Decorator2(Sourcable sourcable){
- super();
- this.sourcable=sourcable;
- }
- public void operation() {
- System.out.println("第2個裝飾器前");
- sourcable.operation();
- System.out.println("第2個裝飾器后");
- }
- }
裝飾器類Decorator3.java 是第三個裝飾器,不同的是它裝飾的內容不一樣,即輸出了不同的字符串。其源代碼如程序
- package pattern.decorator;
- public class Decorator3 implements Sourcable {
- private Sourcable sourcable;
- public Decorator3(Sourcable sourcable){
- super();
- this.sourcable=sourcable;
- }
- public void operation() {
- System.out.println("第3個裝飾器前");
- sourcable.operation();
- System.out.println("第3個裝飾器后");
- }
- }
這時,我們就可以像使用對象的適配器模式一樣來使用這些裝飾器,使用不同的裝飾器就可以達到不同的裝飾效果。如下測試類:首先需要創建一 個源類對象 source ,然后根據將對象使用 Decorator1 來裝飾,並以此使用Decorator2 、 Decorator3 進行裝飾,裝飾后的對象同樣具有與 source 同樣的接口。
- package pattern.decorator;
- public class DecoratorTest {
- /**
- * @param args
- */
- public static void main(String[] args) {
- Sourcable source = new Source();
- // 裝飾類對象
- Sourcable obj = new Decorator1(new Decorator2(new Decorator3(source)));
- obj.operation();
- }
- }
運行該程序的輸出如下:
第1 個裝飾器裝飾前
第2 個裝飾器裝飾前
第3 個裝飾器裝飾前
原始類的方法
第3 個裝飾器裝飾后
第2 個裝飾器裝飾后
第1 個裝飾器裝飾后
從輸出的結果可以看出,原始類對象source 依次被 Decorator1 、 Decorator2 、 Decorator3 進行了裝飾。

