Head First 設計模式之裝飾者模式(Java例子)

前言:

來源於《head first 設計模式》。當作讀書筆記了,這次看的是第三章裝飾者模式。看得有點上癮。。。抽出了點時間來總結一下。

裝飾者模式的概念

動態地將責任附加到對象之上。想要擴展功能,裝飾者提供有別於繼承的另一種選擇。

head fitst基本操作舉個例子

head first裏面舉了兩個例子,一個是星巴克一個我們熟悉的java i/o包。這裏爲了方便就用java i/o來展示我們的裝飾者模式吧。

通用的觀察者模式的uml圖

慣例貼一下uml圖,這是通用的觀察者模式的uml圖,我們看完它再來了解java i/o的會更好理解
在這裏插入圖片描述
Component:作用是規定了同一個父類,讓每一個組件都可以單獨使用或者被裝飾者包含起來。
ConcreteComponent:這是我們要動態地加上新行爲的對象,繼承與Component.
Decorator:這是裝飾者共同需要實現的接口或者繼承的父類,它使每個裝飾者都帶有一個或者說是包含一個組件,即有一個實例變量來保存某一Component
ConcreteDecoraror:裝飾者咯,可以拓展新的方法或者增加新的行爲在舊的行爲後面

Java i/o的uml:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-1h1B6wlP-1586688264037)(https://imgblog.csdnimg.cn/20200412183344793.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F3YWtlX2xxaA==,size_16,color_FFFFFF,t_70)]
並沒有把所有的類都寫出了,寫了幾個點名關係即可了。
InputStream:相當於上方的component
FileInputStream:相當於被修飾的對象
StringBufferInputStream:相當於被修飾的對象
FilterInputStream:修飾者共同的父類了,裏面包含了一個inputstream實例。

LowerCaseInputStream代碼:

public class LowerCaseInputStream extends FilterInputStream {
    protected LowerCaseInputStream(InputStream in) {
        super(in);
    }
    //針對字節流
    public  int read() throws IOException{
        int c=super.read();
        return (c==-1?c:Character.toLowerCase(((char)c)));
    }
    //針對字節數組
    public int read(byte[] b,int offset,int len) throws IOException {
        int result=super.read(b,offset,len);
        for (int i=offset;i<offset+result;i++){
            b[i]= (byte) Character.toLowerCase(((char)b[i]));
        }
        return  result;
    }
}

測試代碼:

public class InputTest {
    public static void main(String[] args) {
        int c;
        try {
        InputStream in=new LowerCaseInputStream(
                new BufferedInputStream(
                new FileInputStream("./test.txt")));
        while ((c=in.read())>=0){
            System.out.print((char)c);
        }
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

總結:

InputStream in=new LowerCaseInputStream(
                new BufferedInputStream(
                new FileInputStream("./test.txt")));

這是平常我們書寫一個讀取類基本的寫法把,類似於套娃。我們可以理解爲我們先用BufferedInputStream修飾了組件FileInputStream,再用我們自己的LowerCaseInputStream修飾了BufferedInputStream。read的方法的調用就先調用FileInputStream從文件中讀取然後到BufferedInputStream用字符流再到LowerCaseInputStream轉化爲小寫,這樣統分體現了裝飾者模式對方法的擴展,又不會影響上層代碼,同時對於java i/o這種類別特別多已經功能又重複,或者再某個類基礎上加強的,最爲適用。
裝飾者模式簡單來講其實就是:動態的給一個對象添加一些額外的功能,而無需修改上層代碼。

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