設計模式之-Decorator--裝飾器模式

Decorator模式也叫裝飾模式,是由GoF提出的23種軟件設計模式的一種。Decorator模式是構造型的設計模式之一,它爲類的實例對象動態追加附加功能,就好像裝飾了對象的行爲。

Decorator模式是構造型的設計模式之一,它可以動態地改變一個對象方法的行爲。

 

Component
原有類的接口
ConcreteComponent
功能實現類。Component的具體實現類
Decorator
裝 飾抽象類。與ConcreteComponent一樣都繼承了Component接口,但實現的方式與ConcreteComponent有區別。 ConcreteComponent通過單純繼承的方式來實現;而Decorator則通過對Component對象的封裝與動作委讓方式來實現。
下面是一個典型的Decorator的代碼爲:
清單1
public class Decorator implement Component {
    Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    public void doSomething() {
        ...
        this.component.doSomething();
        ...
    }
}
ConcreteDecoratorA ConcreteDecorator
具體的裝飾類。Decorator的具體實現類

爲什麼要如清單1所示去構造類的關係呢?或者說,爲什麼不直接使用一般的繼承或其他方法呢?我們通過下面的範例來回答這個問題。

Decorator模式的應用範例

比如,汽車上色的過程:
要對從工廠剛出來的同一種汽車進行上色,
首先給汽車上相同的底色;
然後根據不同的要求,進行下面的操作:
有時希望上黃色;
有時希望上紅色;
有時希望先上黃色,再上紅色;
有時希望先上紅色,再上黃色;

如果要在汽車類中完成上面的功能,不管是通過橫向擴展(爲類增加方法)還是縱向擴展(子類),都很難設計出柔軟的可擴展的類結構。

上述過程用Decorator模式來描述:
汽車抽象類Car相當於Decorator模式類圖中的Component,該接口定義了一個makeColor()方法用來給汽車上色
卡車類Truck相當於ConcreteComponent

上色抽象類MakeColorCar相當於Decorator
上黃色類MakeYellowColorCar與上紅色類MakeRedColorCar就相當於ConcreteDecorator

代碼:

  1. public   class  Client {  
  2.     //測試類   
  3.     public   static   void  main(String[] args) {  
  4.         //生產一輛卡車1(基本色)   
  5.         System.out.println("--Truck 1--" );  
  6.         Car truck = new  Truck();  
  7.                   
  8.         MakeColorCar yellowCar = new  MakeYellowColorCar(truck);  
  9.         MakeColorCar redCar = new  MakeRedColorCar(yellowCar);  
  10.           
  11.         redCar.makeColor();  
  12.           
  13.           
  14.         //生產一輛卡車2(基本色)   
  15.         System.out.println("--Truck 2--" );  
  16.         Car truck2 = new  Truck();  
  17.           
  18.         MakeColorCar redCar2 = new  MakeRedColorCar(truck2);  
  19.         MakeColorCar yellowCar2 = new  MakeYellowColorCar(redCar2);  
  20.           
  21.           
  22.         yellowCar2.makeColor();  
  23.     }  
  24.   
  25. }  
  26.   
  27.   
  28. /**  
  29.  * Component class & subclass  
  30.  *  
  31.  */   
  32. interface  Car {  
  33.     //上色   
  34.     public   void  makeColor();  
  35. }  
  36.   
  37.   
  38. class  Truck  implements  Car {  
  39.   
  40.     public   void  makeColor() {  
  41.         System.out.println("Make basic-color for truck:" );  
  42.     }  
  43. }  
  44.   
  45.   
  46.   
  47. /**  
  48.  * Decorator class & subclass  
  49.  *  
  50.  */   
  51. class  MakeColorCar  implements  Car {  
  52.     protected  Car car;  
  53.       
  54.     public  MakeColorCar(Car car) {  
  55.         this .car = car;  
  56.     }  
  57.       
  58.     public   void  makeColor() {  
  59.         this .car.makeColor();  
  60.     }  
  61. }  
  62.   
  63. class  MakeYellowColorCar  extends  MakeColorCar {  
  64.     public  MakeYellowColorCar(Car car) {  
  65.         super (car);  
  66.     }  
  67.   
  68.     public   void  makeColor() {  
  69.         super .makeColor();  
  70.           
  71.         System.out.println("Add yellow." );  
  72.     }  
  73. }  
  74.   
  75. class  MakeRedColorCar  extends  MakeColorCar {  
  76.     public  MakeRedColorCar(Car car) {  
  77.         super (car);  
  78.     }  
  79.   
  80.     public   void  makeColor() {  
  81.         super .makeColor();  
  82.           
  83.         System.out.println("Add red." );  
  84.     }  
  85. }  
public class Client {
    //測試類
    public static void main(String[] args) {
        //生產一輛卡車1(基本色)
        System.out.println("--Truck 1--");
        Car truck = new Truck();
                
        MakeColorCar yellowCar = new MakeYellowColorCar(truck);
        MakeColorCar redCar = new MakeRedColorCar(yellowCar);
        
        redCar.makeColor();
        
        
        //生產一輛卡車2(基本色)
        System.out.println("--Truck 2--");
        Car truck2 = new Truck();
        
        MakeColorCar redCar2 = new MakeRedColorCar(truck2);
        MakeColorCar yellowCar2 = new MakeYellowColorCar(redCar2);
        
        
        yellowCar2.makeColor();
    }

}


/**
 * Component class & subclass
 *
 */
interface Car {
    //上色
    public void makeColor();
}


class Truck implements Car {

    public void makeColor() {
        System.out.println("Make basic-color for truck:");
    }
}



/**
 * Decorator class & subclass
 *
 */
abstract class MakeColorCar implements Car {
    protected Car car;
    
    public MakeColorCar(Car car) {
        this.car = car;
    }
    
    public void makeColor() {
        this.car.makeColor();
    }
}

class MakeYellowColorCar extends MakeColorCar {
    public MakeYellowColorCar(Car car) {
        super(car);
    }

    public void makeColor() {
        super.makeColor();
        
        System.out.println("Add yellow.");
    }
}

class MakeRedColorCar extends MakeColorCar {
    public MakeRedColorCar(Car car) {
        super(car);
    }

    public void makeColor() {
        super.makeColor();
        
        System.out.println("Add red.");
    }
}




執行Client,輸出結果:

C:/Decorator>javac *.java
C:/Decorator>java Client
--Truck 1--
Make basic-color for truck:
Add yellow.
Add red.
--Truck 2--
Make basic-color for truck:
Add red.
Add yellow.
C:/Decorator>

對於類的不同對象truck1與truck2,我們可以應用Decorator模式改變其行爲:我們爲truck1先上底色,然後上黃色,再上紅色;但爲truck2先上底色,然後上紅色,再上黃色。

Decorator模式與Adapter模式,Bridge模式的區別

有關Adapter模式和Builder模式的介紹,請參考下面2篇文章:
設計模式之Adapter - 適配器模式
設計模式之Bridge - 橋接模式
與Decorator模式一樣,它們具有以下相同點
- 都是構造型的設計模式
- 都是通過新類對原有類的封裝(繼承或委讓的方式)

它們的不同點
- 對象:Adapter強調外部接口,Bridge強調內部實現。Adapter通過提供新的接口形式隱蔽對原有類(功能)的調用,Bridge把同一事物的抽象與具體行爲分離。
- 封裝:Decorator可以不用修改原有對象接口,爲對象增加新的功能或改變其行爲;Adapter如需增加功能,則需修改接口。

  舉例來說,比如有一樣東西,它提供a,b,c等功能,
  採用Adapter模式來實現的話,就等於告訴用戶,我有a, b, c等功能,你可以使用,但這些功能都是通過外部(調用其它類)實現的。
  Bridge則這樣告訴用戶:有一樣東西A,提供某項功能,這項功能可能是a, 或b, 或c功能,用戶自己在使用A時,可以選擇讓A組合a功能(A+a),或b功能(A+b),或c功能(A+c)。
  Decorator則是這樣:有一樣東西A,提供一個基本功能a。另外給它做了具有功能b的封套B,具有功能c的封套C。你可以在使用A時,把A裝進B,或C裏,這樣就具有a+b,或a+c功能了,甚至還可以把裝有A的B裝入到C裏,這樣便具有a+b+c功能了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章