裝飾模式 Decorator
本篇文章轉載自http://c.biancheng.net/view/1366.html
裝飾模式比較簡單,我就不單獨寫實作例子了,參考設計圖去實作不是什么問題,建議可以寫一寫找找感覺,
在現實生活中,常常需要對現有產品增加新的功能或美化其外觀,如房子裝修、相片加相框等,在軟體開發程序中,有時想用一些現存的組件,這些組件可能只是完成了一些核心功能,但在不改變其結構的情況下,可以動態地擴展其功能,所有這些都可以釆用裝飾模式來實作,
裝飾模式的定義與特點
裝飾(Decorator)模式的定義:指在不改變現有物件結構的情況下,動態地給該物件增加一些職責(即增加其額外功能)的模式,它屬于物件結構型模式,
裝飾(Decorator)模式的主要優點有:
- 采用裝飾模式擴展物件的功能比采用繼承方式更加靈活,
- 可以設計出多個不同的具體裝飾類,創造出多個不同行為的組合,
其主要缺點是:裝飾模式增加了許多子類,如果過度使用會使程式變得很復雜,
裝飾模式的結構與實作
通常情況下,擴展一個類的功能會使用繼承方式來實作,但繼承具有靜態特征,耦合度高,并且隨著擴展功能的增多,子類會很膨脹,如果使用組合關系來創建一個包裝物件(即裝飾物件)來包裹真實物件,并在保持真實物件的類結構不變的前提下,為其提供額外的功能,這就是裝飾模式的目標,下面來分析其基本結構和實作方法,
1. 模式的結構
裝飾模式主要包含以下角色,
- 抽象構件(Component)角色:定義一個抽象介面以規范準備接收附加責任的物件,
- 具體構件(Concrete Component)角色:實作抽象構件,通過裝飾角色為其添加一些職責,
- 抽象裝飾(Decorator)角色:繼承抽象構件,并包含具體構件的實體,可以通過其子類擴展具體構件的功能,
- 具體裝飾(ConcreteDecorator)角色:實作抽象裝飾的相關方法,并給具體構件物件添加附加的責任,
裝飾模式的結構圖如圖 1 所示,
2. 模式的實作
裝飾模式的實作代碼如下:
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 只有一個具體裝飾的裝飾模式
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/174092.html
標籤:設計模式
上一篇:結合公司現狀淺談CMDB
下一篇:【Java設計模式】單例模式
