<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 73,  comments - 55,  trackbacks - 0
    ???? JDK為程序員提供了大量的類庫,而為了保持類庫的可重用性,可擴展性和靈活性,其中使用到了大量的設計模式,本文將介紹JDK的I/O包中使用到的Decorator模式,并運用此模式,實現(xiàn)一個新的輸出流類。?

       Decorator模式簡介?

       Decorator模式又名包裝器(Wrapper),它的主要用途在于給一個對象動態(tài)的添加一些額外的職責。與生成子類相比,它更具有靈活性
    有時候,我們需要為一個對象而不是整個類添加一些新的功能,比如,給一個文本區(qū)添加一個滾動條的功能。我們可以使用繼承機制來實現(xiàn)這一功能,但是這種方法不夠靈活,我們無法控制文本區(qū)加滾動條的方式和時機。而且當文本區(qū)需要添加更多的功能時,比如邊框等,需要創(chuàng)建新的類,而當需要組合使用這些功能時無疑將會引起類的爆炸。

       我們可以使用一種更為靈活的方法,就是把文本區(qū)嵌入到滾動條中。而這個滾動條的類就相當于對文本區(qū)的一個裝飾。 這個裝飾(滾動條)必須與被裝飾的組件(文本區(qū))繼承自同一個接口,這樣,用戶就不必關心裝飾的實現(xiàn),因為這對他們來說是透明的。裝飾會將用戶的請求轉(zhuǎn)發(fā) 給相應的組件(即調(diào)用相關的方法),并可能在轉(zhuǎn)發(fā)的前后做一些額外的動作(如添加滾動條)。通過這種方法,我們可以根據(jù)組合對文本區(qū)嵌套不同的裝飾,從而 添加任意多的功能。這種動態(tài)的對對象添加功能的方法不會引起類的爆炸,也具有了更多的靈活性。

       以上的方法就是Decorator模式,它通過給對象添加裝飾來動態(tài)的添加新的功能。如下是Decorator模式的UML圖:



       Component為組件和裝飾的公共父類,它定義了子類必須實現(xiàn)的方法。

       ConcreteComponent是一個具體的組件類,可以通過給它添加裝飾來增加新的功能。

       Decorator是所有裝飾的公共父類,它定義了所有裝飾必須實現(xiàn)的方法,同時,它還保存了一個對于Component的引用,以便將用戶的請求轉(zhuǎn)發(fā)給Component,并可能在轉(zhuǎn)發(fā)請求前后執(zhí)行一些附加的動作。

       ConcreteDecoratorA和ConcreteDecoratorB是具體的裝飾,可以使用它們來裝飾具體的Component。

      Java IO包中的Decorator模式

       JDK提供的java.io包中使用了Decorator模式來實現(xiàn)對各種輸入輸出流的封裝。以下將以java.io.OutputStream及其子類為例,討論一下Decorator模式在IO中的使用。

       首先來看一段用來創(chuàng)建IO流的代碼:

    以下是代碼片段:
    try {
      OutputStream out = new DataOutputStream(new FileOutputStream("test.txt"));
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }

       這段代碼對于使用過JAVA輸入輸出流的人來說再熟悉不過了,我們使用DataOutputStream封裝了一個FileOutputStream。 這是一個典型的Decorator模式的使用,F(xiàn)ileOutputStream相當于Component,DataOutputStream就是一個 Decorator。將代碼改成如下,將會更容易理解:

    以下是代碼片段:
    try {
      OutputStream out = new FileOutputStream("test.txt");
      out = new DataOutputStream(out);
    } catch(FileNotFoundException e) {
      e.printStatckTrace();
    }

       由于FileOutputStream和DataOutputStream有公共的父類OutputStream,因此對對象的裝飾對于用戶來說幾乎是透明的。下面就來看看OutputStream及其子類是如何構成Decorator模式的:



       OutputStream是一個抽象類,它是所有輸出流的公共父類,其源代碼如下:

    以下是代碼片段:
    public abstract class OutputStream implements Closeable, Flushable {
      public abstract void write(int b) throws IOException;
      ...
    }

       它定義了write(int b)的抽象方法。這相當于Decorator模式中的Component類。

       ByteArrayOutputStream,F(xiàn)ileOutputStream 和 PipedOutputStream 三個類都直接從OutputStream繼承,以ByteArrayOutputStream為例:

    以下是代碼片段:
    public class ByteArrayOutputStream extends OutputStream {
      protected byte buf[];
      protected int count;
      public ByteArrayOutputStream() {
       this(32);
      }
      public ByteArrayOutputStream(int size) {
       if (size 〈 0) {
        throw new IllegalArgumentException("Negative initial size: " + size);
       }
       buf = new byte[size];
      }
      public synchronized void write(int b) {
       int newcount = count + 1;
       if (newcount 〉 buf.length) {
        byte newbuf[] = new byte[Math.max(buf.length 〈〈 1, newcount)];
        System.arraycopy(buf, 0, newbuf, 0, count);
        buf = newbuf;
       }
       buf[count] = (byte)b;
       count = newcount;
      }
      ...
    }

       它實現(xiàn)了OutputStream中的write(int b)方法,因此我們可以用來創(chuàng)建輸出流的對象,并完成特定格式的輸出。它相當于Decorator模式中的ConcreteComponent類。

       接著來看一下FilterOutputStream,代碼如下:

    以下是代碼片段:
    public class FilterOutputStream extends OutputStream {
      protected OutputStream out;
      public FilterOutputStream(OutputStream out) {
       this.out = out;
      }
     public void write(int b) throws IOException {
       out.write(b);
      }
     ...
    }

       同樣,它也是從OutputStream繼承。但是,它的構造函數(shù)很特別,需要傳遞一個OutputStream的引用給它,并且它將保存對此對象的引 用。而如果沒有具體的OutputStream對象存在,我們將無法創(chuàng)建FilterOutputStream。由于out既可以是指向 FilterOutputStream類型的引用,也可以是指向ByteArrayOutputStream等具體輸出流類的引用,因此使用多層嵌套的方 式,我們可以為ByteArrayOutputStream添加多種裝飾。這個FilterOutputStream類相當于Decorator模式中的 Decorator類,它的write(int b)方法只是簡單的調(diào)用了傳入的流的write(int b)方法,而沒有做更多的處理,因此它本質(zhì)上沒有對流進行裝飾,所以繼承它的子類必須覆蓋此方法,以達到裝飾的目的。

       BufferedOutputStream 和 DataOutputStream是FilterOutputStream的兩個子類,它們相當于Decorator模式中的 ConcreteDecorator,并對傳入的輸出流做了不同的裝飾。以BufferedOutputStream類為例:

    以下是代碼片段:
    public class BufferedOutputStream extends FilterOutputStream {
      ...
      private void flushBuffer() throws IOException {
       if (count 〉 0) {
        out.write(buf, 0, count);
        count = 0;
       }
      }
      public synchronized void write(int b) throws IOException {
       if (count 〉= buf.length) {
        flushBuffer();
       }
       buf[count++] = (byte)b;
      }
      ...
    }


       這個類提供了一個緩存機制,等到緩存的容量達到一定的字節(jié)數(shù)時才寫入輸出流。首先它繼承了FilterOutputStream,并且覆蓋了父類的 write(int b)方法,在調(diào)用輸出流寫出數(shù)據(jù)前都會檢查緩存是否已滿,如果未滿,則不寫。這樣就實現(xiàn)了對輸出流對象動態(tài)的添加新功能的目的。

       下面,將使用Decorator模式,為IO寫一個新的輸出流。

       自己寫一個新的輸出流

       了解了OutputStream及其子類的結(jié)構原理后,我們可以寫一個新的輸出流,來添加新的功能。這部分中將給出一個新的輸出流的例子,它將過濾待輸出語句中的空格符號。比如需要輸出"java?io?OutputStream",則過濾后的輸出為"javaioOutputStream"。以下為SkipSpaceOutputStream類的代碼:


    以下是代碼片段:
    import?java.io.FilterOutputStream;?
    import?java.io.IOException;?
    import?java.io.OutputStream;?
    /**?
    *?A?new?output?stream,?which?will?check?the?space?character?
    *?and?won't?write?it?to?the?output?stream.?
    *?@author?Magic?
    *?
    */?
    public?class?SkipSpaceOutputStream?extends?FilterOutputStream?{?
      public?SkipSpaceOutputStream(OutputStream?out)?{?
       super(out);?
      }?
      /**?
      *?Rewrite?the?method?in?the?parent?class,?and?
      *?skip?the?space?character.?
      */?
      public?void?write(int?b)?throws?IOException{?
       if(b!='?'){?
        super.write(b);?
       }?
      }?
    }

       它從FilterOutputStream繼承,并且重寫了它的write(int?b)方法。在write(int?b)方法中首先對輸入字符進行了檢查,如果不是空格,則輸出。

       以下是一個測試程序:


    以下是代碼片段:
    import?java.io.BufferedInputStream;?
    import?java.io.DataInputStream;?
    import?java.io.DataOutputStream;?
    import?java.io.IOException;?
    import?java.io.InputStream;?
    import?java.io.OutputStream;?
    /**?
    *?Test?the?SkipSpaceOutputStream.?
    *?@author?Magic?
    *?
    */?
    public?class?Test?{?
      public?static?void?main(String[]?args){?
       byte[]?buffer?=?new?byte[1024];?

       /**?
       *?Create?input?stream?from?the?standard?input.?
       */?
       InputStream?in?=?new?BufferedInputStream(new?DataInputStream(System.in));?

       /**?
       *?write?to?the?standard?output.?
       */?
       OutputStream?out?=?new?SkipSpaceOutputStream(new?DataOutputStream(System.out));?

       try?{?
        System.out.println("Please?input?your?words:?");?
        int?n?=?in.read(buffer,0,buffer.length);?
        for(int?i=0;i< n;i++){?
         out.write(buffer[i]);?
        }?
       }?catch?(IOException?e)?{?
        e.printStackTrace();?
       }?
      }?
    }

       執(zhí)行以上測試程序,將要求用戶在console窗口中輸入信息,程序?qū)⑦^濾掉信息中的空格,并將最后的結(jié)果輸出到console窗口。比如:


    以下是引用片段:
    Please?input?your?words:?
    a?b?c?d?e?f?
    abcdef

       總?結(jié)

       在java.io包中,不僅OutputStream用到了Decorator設計模式,InputStream,Reader,Writer等都用到了此模式。而作為一個靈活的,可擴展的類庫,JDK中使用了大量的設計模式,比如在Swing包中的MVC模式,RMI中的Proxy模式等等。對于JDK中模式的研究不僅能加深對于模式的理解,而且還有利于更透徹的了解類庫的結(jié)構和組成。?



    ------------------------------------




    decorator?for?non-visualable?class?e.g.?java.io.*

    The?class?FilterInputStream?itself?simply?overrides?all?methods?of?InputStream?with?versions?that?pass?all?requests?to?the?underlying?input?stream.?Subclasses?of?FilterInputStream?may?further?override?some?of?these?methods?as?well?as?provide?additional?methods?and?fields.?

    The?FilterInputStream?class?is?thus?a?Decorator?that?can?be?wrapped?around?any?input?stream?class.?It?is?essentially?an?abstract?class?that?doesn’t?do?any?processing,?but?provides?a?layer?where?the?relevant?methods?have?been?duplicated.?It?normally?forwards?these?method?calls?to?the?enclosed?parent?stream?class.?The?interesting?classes?derived?from?FilterInputStream?include:?

    BufferedInputStream?Adds?buffering?to?stream?so?that?every?call?does

    not?cause?I/O?to?occur.

    CheckedInputStream??Maintains?a?checksum?of?bytes?as?they?are?read

    DataInputStream?????Reads?primitive?types?(Long,?Boolean,?Float,?etc.)

    from?the?input?stream.

    DigestInputStream???Computes?a?MessageDigest?of?any?input?stream.

    InflaterInputStream?Implements?methods?for?uncompressing?data.

    PushbackInputStream?Provides?a?buffer?where?data?can?be?“unread,”?if

    during?parsing?you?discover?you?need?to?back?up.
    posted on 2006-07-19 16:02 保爾任 閱讀(484) 評論(0)  編輯  收藏 所屬分類: Design Patten

    <2025年7月>
    293012345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    常用鏈接

    留言簿(4)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲午夜久久久影院伊人| 成人爱做日本视频免费| 亚洲精品无码专区在线在线播放| 美女视频黄a视频全免费网站一区| 久久久久国产精品免费免费搜索| 亚洲男人电影天堂| 久久久久久久免费视频| 亚洲情A成黄在线观看动漫软件 | 又大又硬又爽又粗又快的视频免费| 亚洲伊人久久精品影院| a成人毛片免费观看| 亚洲AV无码一区东京热久久| 99久久99久久精品免费观看| 67pao强力打造67194在线午夜亚洲 | 四虎影院免费视频| 亚洲爆乳精品无码一区二区| 免费真实播放国产乱子伦| eeuss草民免费| 亚洲福利在线视频| 免费国产成人高清在线观看网站| 亚洲中文字幕久久精品无码A| 日韩一区二区三区免费体验| 四虎精品成人免费视频| 久久夜色精品国产亚洲| 在线a免费观看最新网站| 亚洲色大成WWW亚洲女子| 国产乱子伦精品免费无码专区| 国产精品九九久久免费视频 | 男女作爱在线播放免费网站| 日韩亚洲Av人人夜夜澡人人爽| 91成人免费在线视频| 亚洲av无码无线在线观看| 亚洲精品国产美女久久久| 16女性下面扒开无遮挡免费| 亚洲国产午夜精品理论片在线播放| 亚洲乱码国产一区网址| 精品无码人妻一区二区免费蜜桃| 亚洲欧美成人综合久久久| 国产成人A亚洲精V品无码| 999久久久免费精品国产| 人妻18毛片a级毛片免费看|