歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 裝飾器模式詳解

裝飾器模式詳解

日期:2017/3/1 9:06:16   编辑:Linux編程

目的:動態地給一個對象添加一些額外的職責。一般我們為了擴展一個類經常使用繼承方式實現,由於繼承為類引入靜態特征,並且隨著擴展功能的增多,子類會很膨脹。在不想增加很多子類的情況下擴展類。將具體功能職責劃分,同時繼承裝飾者模式。

使用場景:

(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,就可以提供一個內存緩沖區來保存從文件中讀取的輸入流。

Copyright © Linux教程網 All Rights Reserved