天天看點

設計模式之八 --- 裝飾模式(Decorator)

【1】基本概念

          裝飾模式(Decorator),動态地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。

【2】簡單分析

          我們先來看下該設計模式的UML結構圖

設計模式之八 --- 裝飾模式(Decorator)

上圖是Decorator 模式的結構圖,讓我們可以進行更友善的描述:

Component是定義一個對象接口,可以給這些對象動态地添加職責。

ConcreteComponent是定義了一個具體的對象,也可以給這個對象添加一些職責。

Decorator是裝飾抽象類,繼承了Component,從外類來擴充Component類的功能,但對于Component來說,是無需知道Decorator存在的。

ConcreteDecorator就是具體的裝飾對象,起到給Component添加職責的功能。

【3】如何用Java語音來實作該設計模式

假設情景:某人裝扮自己形象,穿衣服,褲子,鞋子,戴帽子等來把自己給包裝起來,需要把所需的功能按正确的順序串聯起來進行控制,我們應該如何設計才能做到呢?如下,先看下代碼結構圖:

設計模式之八 --- 裝飾模式(Decorator)

3.1 先建立一個接口類:Component.java 

package com.andyidea.patterns.component;  
  
public interface Component {  
      
    void show();  
  
}  
           

 3.2 建立一個具體的 ConcreteComponent 來實作 Component 接口:Person.java

package com.andyidea.patterns.concretecomponent;  
  
import com.andyidea.patterns.component.Component;  
  
public class Person implements Component{  
      
    private String name;  
      
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public Person(String name){  
        this.name = name;  
    }  
  
    @Override  
    public void show() {  
        System.out.println("裝扮的" + name);  
    }  
  
}  
3.3 建立裝飾類 Decorator 實作 Component 接口
[html] view plaincopy
package com.andyidea.patterns.decorator;  
  
import com.andyidea.patterns.component.Component;  
  
public class Decorator implements Component{  
      
    private Component mComponent;  
      
    public void decoratorObj(Component component){  
        mComponent = component;  
    }  
  
    @Override  
    public void show() {  
          
        if(mComponent != null){  
            mComponent.show();  
        }  
    }  
  
}  
3.4 分别建立具體的裝飾類:Jeans.java , Pelisse.java, Sandal.java ...等等,分别繼承 Decorator.java 類:
[html] view plaincopy
package com.andyidea.patterns.concretedecorator;  
  
import com.andyidea.patterns.decorator.Decorator;  
  
/** 牛仔褲 */  
public class Jeans extends Decorator {  
  
    @Override  
    public void show(){  
        System.out.println("穿牛仔褲");  
        super.show();  
    }  
      
}  
其餘類類似,在這裡就省略了。
3.5 用戶端測試類:
[html] view plaincopy
package com.andyidea.patterns;  
  
import com.andyidea.patterns.concretecomponent.Person;  
import com.andyidea.patterns.concretedecorator.Jeans;  
import com.andyidea.patterns.concretedecorator.Sandal;  
import com.andyidea.patterns.concretedecorator.TShirt;  
  
/**  
 * 裝飾模式測試用戶端  
 * @author Andy.Chen  
 *  
 */  
public class DecoratorClient {  
  
    public static void main(String[] args) {  
        System.out.println("Welcome to Andy.Chen Blog!" +"\n"   
                   +"Decorator Patterns." +"\n");  
          
        Person mPerson = new Person("Andy");  
          
        Sandal mSandal = new Sandal();  
        Jeans mJeans = new Jeans();  
        TShirt mShirt = new TShirt();  
          
        mShirt.decoratorObj(mPerson);  
        mJeans.decoratorObj(mShirt);  
        mSandal.decoratorObj(mJeans);  
        mSandal.show();  
          
    }  
      
}  
【4】測試顯示輸出的結果如下:
[html] view plaincopy
Welcome to Andy.Chen Blog!  
Decorator Patterns.  
  
穿涼鞋  
穿牛仔褲  
穿T-Shirt  
裝扮的Andy  
           

 【5】總結: Decorator模式有以下的優缺點:

1. 比靜态繼承更靈活 與對象的靜态繼承相比, Decorator 模式提供了更加靈活的向對象添加職責的方式,可以使用添加和分離的方法,用裝飾在運作時刻增加和删除職責。使用繼承機制增加職責需要建立一個新的子類,如果需要為原來所有的子類都添加功能的話,每個子類都需要重寫,增加系統的複雜度,此外可以為一個特定的 Component 類提供多個 Decorator ,這種混合比對是适用繼承很難做到的。 2. 避免在層次結構高層的類有太多的特征, Decorator 模式提供了一種“即用即付”的方法來添加職責,他并不試圖在一個複雜的可訂制的類中支援所有可預見的特征,相反可以定義一個簡單的類,并且用 Decorator 類給他逐漸的添加功能,可以從簡單的部件組合出複雜的功能。 3. Decorator  與它的 Component 不一樣  Decorator 是一個透明的包裝,如果我們從對象辨別的觀點出發,一個被裝飾了的元件與這個元件是有差别的,是以使用裝飾時不應該以來對象辨別。 4. 産生許多小對象,采用 Decorator 模式進行系統設計往往會産生許多看上去類似的小對象,這些對象僅僅在他們互相連接配接的方式上有所不同。

繼續閱讀