目的:動態地給一個對象添加一些額外的職責。一般我們為了擴展一個類經常使用繼承方式實現,由於繼承為類引入靜態特征,並且隨著擴展功能的增多,子類會很膨脹。在不想增加很多子類的情況下擴展類。將具體功能職責劃分,同時繼承裝飾者模式。
使用場景:
(1)需要在不影響其他對象的情況下,以動態、透明的方式給對象添加職責。
(2)如果不適合使用子類來進行擴展的時候,可以考慮使用裝飾器模式。
具體例子:
(1)組件對象的接口,可以給這些對象動態的添加職責 public abstract class Component { /** * 示例方法 */ public abstract void operation(); } (2)具體實現組件對象接口的對象 public class ConcreteComponent extends Component { public void operation() { //相應的功能處理 } } (3)裝飾器接口,維持一個指向組件對象的接口對象, 並定義一個與組件接口一致的接口 public abstract class Decorator extends Component { /** * 持有組件對象 */ protected Component component; /** * 構造方法,傳入組件對象 * @param component 組件對象 */ public Decorator(Component component) { this.component = component; } public void operation() { //轉發請求給組件對象,可以在轉發前後執行一些附加動作 component.operation(); } } (4)裝飾器的具體實現對象,向組件對象添加職責,operationFirst(),operationLast()為前後需要添加的功能。具體的裝飾器類ConcreteDecoratorB代碼相似,不在給出。 public class ConcreteDecoratorA extends Decorator { public ConcreteDecoratorA(Component component) { super(component); } private void operationFirst(){ } //在調用父類的operation方法之前需要執行的操作 private void operationLast(){ } //在調用父類的operation方法之後需要執行的操作 public void operation() { //調用父類的方法,可以在調用前後執行一些附加動作 operationFirst(); //添加的功能 super.operation(); //這裡可以選擇性的調用父類的方法,如果不調用則相當於完全改寫了方法,實現了新的功能 operationLast(); //添加的功能 } } (5) 客戶端使用裝飾器的代碼 public class Client{ public static void main(String[] args){ Component c1 = new ConcreteComponent (); //首先創建需要被裝飾的原始對象(即要被裝飾的對象) Decorator decoratorA = new ConcreteDecoratorA(c1); //給對象透明的增加功能A並調用 decoratorA .operation(); Decorator decoratorB = new ConcreteDecoratorB(c1); //給對象透明的增加功能B並調用 decoratorB .operation(); Decorator decoratorBandA = new ConcreteDecoratorB(decoratorA);//裝飾器也可以裝飾具體的裝飾對象,此時相當於給對象在增加A的功能基礎上在添加功能B decoratorBandA.operation(); } }
經典例子:
BufferedInputStream bis =
new
BufferedInputStream(
new
FileInputStream(file));
//其中file為某個具體文件的File或者FileDescription對象
Java中的IO是明顯的裝飾器模式的運用。FilterInputStream,FilterOutputStream,FilterRead,FilterWriter分別為具體裝飾器的父類,相當於Decorator類,它們分別實現了InputStream,OutputStream,Reader,Writer類(這些類相當於Component,是其他組件類的父類,也是Decorator類的父類)。繼承自InputStream,OutputStream,Reader,Writer這四個類的其他類是具體的組件類,每個都有相應的功能,相當於ConcreteComponent類。而繼承自FilterInputStream,FilterOutputStream,FilterRead,FilterWriter這四個類的其他類就是具體的裝飾器對象類,即ConcreteDecorator類。通過這些裝飾器類,可以給我們提供更加具體的有用的功能。如FileInputStream是InputStream的一個子類,從文件中讀取數據流,BufferedInputStream是繼承自FilterInputStream的具體的裝飾器類,該類提供一個內存的緩沖區類保存輸入流中的數據。我們使用如下的代碼來使用BufferedInputStream裝飾FileInputStream,就可以提供一個內存緩沖區來保存從文件中讀取的輸入流。