《設計模式》-- 裝飾模式

裝飾模式

認識

動態地給一個對象添加一系列額外的職責,比子類繼承更加靈活可配。

透明式裝飾模式:裝飾對象和被裝飾對象實現完全相同的接口,或者裝飾對象完全繼承被裝飾對象,裝飾對象沒有定義額外的方法實現。

半透明裝飾模式:裝飾對象在實現被裝飾對象的接口或者繼承被裝飾對象之外,還有單獨額外的自定義方法。這時裝飾角色實際上已經成爲一個適配器角色。適配器類的接口會比被裝飾的目標類接口寬。

思考

靈活的爲對象添加額外的功能,實現數量、順序的可動態配置,搭配工廠模式、策略模式,實現靈活組合實現複雜功能。

按照流程拆分功能,將功能面向對象設計,垂直、可選、有序的組合功能,最先執行的最先被包裝

AOP的實現

本質:對象動態組合

使用場景

  • 在不影響其他對象的情況下,以動態、透明的方式給對象添加職責
  • 如果不適合使用子類進行擴展功能的時候,使用裝飾模式,裝飾模式使用對象組合方式,避免由於功能複雜需要創建太多子類的問題

優缺點

  • 優點

    1. 裝飾模式與繼承關係的目的都是要擴展對象的功能,但是裝飾模式可以提供比繼承更多的靈活性。裝飾模式允許系統動態決定“貼上”一個需要的“裝飾”,或者除掉一個不需要的“裝飾”。繼承關係則不同,繼承關係是靜態的,它在系統運行前就決定了。
    2. 通過使用不同的具體裝飾類以及這些裝飾類的排列組合,設計師可以創造出很多不同行爲的組合。
  • 缺點

    1. 由於使用裝飾模式,可以比使用繼承關係需要較少數目的類。使用較少的類,當然使設計比較易於進行。但是,在另一方面,使用裝飾模式會產生比使用繼承關係更多的對象。更多的對象會使得查錯變得困難,特別是這些對象看上去都很相像。

UML圖

裝飾對象和被裝飾對象實現同一個接口(或裝飾對象繼承被裝飾對象),裝飾接口中持有一個被裝飾對象進行操作

image

抽象構件(Component)角色:給出一個抽象接口,以規範準備接收附加責任的對象。

具體構件(ConcreteComponent)角色:定義一個將要接收附加責任的類。

裝飾(Decorator)角色:持有一個構件(Component)對象的實例,實現Component接口

具體裝飾(ConcreteDecorator)角色: 對持有的Component對象實例進行進一步操作

代碼實現

裝飾對象通過構造函數持有一個被裝飾對象,裝飾對象和被裝飾對象實現同一個接口,或者裝飾對象繼承被裝飾對象,在裝飾對象中調用方法時先調用被裝飾對象中的方法,然後在執行裝飾對象的相關業務代碼,相當於對被裝飾對象進行一次包裝。

由於被裝飾對象和裝飾對象實現同一個接口,所以在裝飾對象的實現類中可以對被裝飾對象再次進行包裝。這樣層級調用,先調用被裝飾對象中的方法,然後一層層往上調用。

//接口
public interface Component {    
    public void sampleOperation();
}
//被裝飾對象
public class ConcreteComponent implements Component {
    @Override
    public void sampleOperation() {
        // 寫相關的業務代碼
    }
}
//裝飾對象 實現被裝飾對象實現的接口
public class Decorator implements Component{
    // 持有一個被裝飾對象
    private Component component;
    //通過構造傳入
    public Decorator(Component component){
        this.component = component;
    }
    @Override
    public void sampleOperation() {
        // 委派給構件
        component.sampleOperation();
    }   
}
//裝飾對象實現類
public class ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    @Override
    public void sampleOperation() {
     super.sampleOperation();
        // 寫相關的業務代碼
    }
}
//裝飾對象實現類
public class ConcreteDecoratorB extends Decorator {

    public ConcreteDecoratorB(Component component) {
        super(component);
    }
    @Override
    public void sampleOperation() {
      super.sampleOperation();
        // 寫相關的業務代碼
    }
}

源碼分析

image

●  抽象構件(Component)角色:由InputStream扮演。這是一個抽象類,爲各種子類型提供統一的接口。

●  **具體構件(ConcreteComponent)角色:**ByteArrayInputStream、FileInputStream、PipedInputStream、StringBufferInputStream直接繼承了InputStream,扮演具體構件。它們實現了抽象構件角色所規定的接口。

●  抽象裝飾(Decorator)角色:由FilterInputStream扮演。它實現了InputStream所規定的接口。

●  具體裝飾(ConcreteDecorator)角色:由幾個類扮演,分別是BufferedInputStream、DataInputStream以及兩個不常用到的類LineNumberInputStream、PushbackInputStream。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章