Java設計模式--裝飾器模式到Java IO 流


裝飾器模式

抽象構件角色:給出一個抽象接口,以規范准備接受附加責任的對象。

具體構件角色:定義准備接受附加責任的對象。

抽象裝飾角色:持有一個構件對象的實例,並對應一個與抽象構件接口一致的接口。

具體裝飾角色:負責給具體構件加上額外的責任。

什么時候使用:

1. 需要擴展一個類的功能,或者給一個類增加附加責任。

2. 需要動態的給一個對象增加功能,這些功能可以再動態的撤銷。

3. 需要增加由一些基本功能的排列組合而產生的的大量的功能,從而使繼承關系變得不現實。

我以給汽車換顏色為例:

汽車廠生產汽車實例,4S店可以噴漆換顏色。

Car接口:

/**
 * Created by 001977 on 2019-04-12 11:39.
 * 抽象構件角色
 */
public interface Car {

    /**
     * 出廠車身顏色
     */
    void skin();
}

 

具體構件卡羅拉:

/**
 * Created by 001977 on 2019-04-12 11:42.
 * 具體構件:COROLLA卡羅拉(灰色)
 */
public class Corolla implements Car {

    @Override
    public void skin() {
        System.out.println("超級無敵灰色");
    }
}

 

4S店抽象裝飾器:

/**
 * Created by 001977 on 2019-04-12 11:45.
 * 抽象裝飾角色(4S店)
 */
public abstract class FourS implements Car {

    private Car car;

    public FourS(Car car) {
        this.car = car;
    }

    @Override
    public void skin() {
        car.skin();
    }
}

 

具體裝飾器:噴槍紅

/**
 * Created by 001977 on 2019-04-12 11:49.
 * 具體裝飾角色(紅色噴漆)
 */
public class RedSprayPaint extends FourS {

    public RedSprayPaint(Car car) {
        super(car);
    }

    @Override
    public void skin() {
        super.skin();
        System.out.println("花2000塊錢噴紅色的漆");
    }
}

 

具體裝飾器:噴槍白

/**
 * Created by 001977 on 2019-04-12 11:49.
 * 具體裝飾角色(白色噴漆)
 */
public class WhiteSprayPaint extends FourS {

    public WhiteSprayPaint(Car car) {
        super(car);
    }

    @Override
    public void skin() {
        super.skin();
        System.out.println("花1000塊錢噴白色的漆");
    }
}

 

測試運行:

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println("====================出廠顏色====================");
        Car corolla = new Corolla();
        corolla.skin();
        System.out.println("====================換顏色====================");
        RedSprayPaint red = new RedSprayPaint(new WhiteSprayPaint(corolla));
        red.skin();
    }
}

 

 

IO中的體現(以InputStream為例)

抽象構件角色:由InputStream扮演,這個抽象類為各種子類型流處理器提供統一的接口。

具體構件角色:由FileInputStream、ObjectInputStream 、ByteArrayInputStream 等原始流處理器扮演,他們實現了InputStream的接口,可以被裝飾器裝飾。

抽象裝飾角色:由FilterInputStream扮演,他也實現了InputStream的接口。

具體裝飾角色:由DataInputStream 、BufferedInputStream等扮演。

..

由於IO庫中需要很多性能的各種組合,如果用繼承方法實現,那么每一種組合都需要一個類,這樣會造成大量性能重復的類出現。如果使用裝飾器模式,那么類的數目大大減少,性能的重復也減到最少。因此裝飾器模式是IO中的基本模式。

以InputStream【抽象構件】為例:上圖中的流可以分為兩類:原始流處理器【具體構件】(FileInputStream及其左邊的類)和鏈接流處理器【裝飾器】(實現FilterInputStream的類【具體裝飾器】)。

首先InputStream定義了一些規范:

接着比如FileInputStream去實現,實際上它都是去調用本地方法的,請看:

然后裝飾器也去實現InputStream的方法,關鍵是持有InputStream對象的實例

 

最后具體的裝飾器比如:

BufferedInputStream裝飾了InputStream的內部工作方式,使得流的讀入操作使用緩沖機制,不會對每一次流讀入的操作都產生一次物理讀盤動作,從而提高了程序的效率。它的內部有個buf字節數組用來緩存數據。

讀取的時候調用fill方法,簡單來說就是先嘗試獲取緩沖區,然后再操作輸入流將數據讀入緩沖區,這期間還有一些細節比如調整pos不再贅述。

還有DataInputStream提供了一些直接讀取某種類型的數據的方法,省的我們讀取完再去做轉換。

比如:readBoolean

它的讀入操作read方法就是直接調用原始流處理器的方法,並不復雜

 最后附上一張畫了一天的IO繼承關系圖:

 如果圖片看不清,鼠標右鍵---在新標簽頁下打開圖片


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM