詳解JAVA面向對象的設計模式 (七)、裝飾模式

裝飾模式 Decorator

本篇文章轉載自http://c.biancheng.net/view/1366.htmlhtml

裝飾模式比較簡單,我就不單獨寫實現例子了。參考設計圖去實現不是什麼問題。建議能夠寫一寫找找感受。java

在現實生活中,經常須要對現有產品增長新的功能或美化其外觀,如房子裝修、相片加相框等。在軟件開發過程當中,有時想用一些現存的組件。這些組件可能只是完成了一些核心功能。但在不改變其結構的狀況下,能夠動態地擴展其功能。全部這些均可以釆用裝飾模式來實現。this

裝飾模式的定義與特色

裝飾(Decorator)模式的定義:指在不改變現有對象結構的狀況下,動態地給該對象增長一些職責(即增長其額外功能)的模式,它屬於對象結構型模式。.net

裝飾(Decorator)模式的主要優勢有:設計

  • 採用裝飾模式擴展對象的功能比採用繼承方式更加靈活。
  • 能夠設計出多個不一樣的具體裝飾類,創造出多個不一樣行爲的組合。

其主要缺點是:裝飾模式增長了許多子類,若是過分使用會使程序變得很複雜。code

裝飾模式的結構與實現

一般狀況下,擴展一個類的功能會使用繼承方式來實現。但繼承具備靜態特徵,耦合度高,而且隨着擴展功能的增多,子類會很膨脹。若是使用組合關係來建立一個包裝對象(即裝飾對象)來包裹真實對象,並在保持真實對象的類結構不變的前提下,爲其提供額外的功能,這就是裝飾模式的目標。下面來分析其基本結構和實現方法。component

1. 模式的結構

裝飾模式主要包含如下角色。htm

  1. 抽象構件(Component)角色:定義一個抽象接口以規範準備接收附加責任的對象。
  2. 具體構件(Concrete Component)角色:實現抽象構件,經過裝飾角色爲其添加一些職責。
  3. 抽象裝飾(Decorator)角色:繼承抽象構件,幷包含具體構件的實例,能夠經過其子類擴展具體構件的功能。
  4. 具體裝飾(ConcreteDecorator)角色:實現抽象裝飾的相關方法,並給具體構件對象添加附加的責任。

裝飾模式的結構圖如圖 1 所示。對象

2. 模式的實現

裝飾模式的實現代碼以下:blog

package decorator;
public class DecoratorPattern
{
    public static void main(String[] args)
    {
        Component p=new ConcreteComponent();
        p.operation();
        System.out.println("---------------------------------");
        Component d=new ConcreteDecorator(p);
        d.operation();
    }
}
//抽象構件角色
interface  Component
{
    public void operation();
}
//具體構件角色
class ConcreteComponent implements Component
{
    public ConcreteComponent()
    {
        System.out.println("建立具體構件角色");       
    }   
    public void operation()
    {
        System.out.println("調用具體構件角色的方法operation()");           
    }
}
//抽象裝飾角色
class Decorator implements Component
{
    private Component component;   
    public Decorator(Component component)
    {
        this.component=component;
    }   
    public void operation()
    {
        component.operation();
    }
}
//具體裝飾角色
class ConcreteDecorator extends Decorator
{
    public ConcreteDecorator(Component component)
    {
        super(component);
    }   
    public void operation()
    {
        super.operation();
        addedFunction();
    }
    public void addedFunction()
    {
        System.out.println("爲具體構件角色增長額外的功能addedFunction()");           
    }
}

程序運行結果以下:

建立具體構件角色
調用具體構件角色的方法operation()
---------------------------------
調用具體構件角色的方法operation()
爲具體構件角色增長額外的功能addedFunction()

裝飾模式的結構圖

裝飾模式的應用場景

前面講解了關於裝飾模式的結構與特色,下面介紹其適用的應用場景,裝飾模式一般在如下幾種狀況使用。

  • 當須要給一個現有類添加附加職責,而又不能採用生成子類的方法進行擴充時。例如,該類被隱藏或者該類是終極類或者採用繼承方式會產生大量的子類。
  • 當須要經過對現有的一組基本功能進行排列組合而產生很是多的功能時,採用繼承關係很難實現,而採用裝飾模式卻很好實現。
  • 當對象的功能要求能夠動態地添加,也能夠再動態地撤銷時。

裝飾模式在 Java 語言中的最著名的應用莫過於 Java I/O 標準庫的設計了。例如,InputStream 的子類 FilterInputStream,OutputStream 的子類 FilterOutputStream,Reader 的子類 BufferedReader 以及 FilterReader,還有 Writer 的子類 BufferedWriter、FilterWriter 以及 PrintWriter 等,它們都是抽象裝飾類。

下面代碼是爲 FileReader 增長緩衝區而採用的裝飾類 BufferedReader 的例子:

BufferedReader in=new BufferedReader(new FileReader("filename.txt"));
String s=in.readLine();

裝飾模式的擴展

裝飾模式所包含的 4 個角色不是任什麼時候候都要存在的,在有些應用環境下模式是能夠簡化的,如如下兩種狀況。

(1) 若是隻有一個具體構件而沒有抽象構件時,可讓抽象裝飾繼承具體構件,其結構圖如圖 4 所示。

只有一個具體構件的裝飾模式
圖4 只有一個具體構件的裝飾模式

(2) 若是隻有一個具體裝飾時,能夠將抽象裝飾和具體裝飾合併,其結構圖如圖 5 所示。

只有一個具體裝飾的裝飾模式 圖5 只有一個具體裝飾的裝飾模式

相關文章
相關標籤/搜索