??xml version="1.0" encoding="utf-8" standalone="yes"?>香蒸焦蕉伊在线,婷婷成人影院,飘雪影院手机免费高清版在线观看 http://www.aygfsteel.com/eric0326/java技术,软g工程Q开源相?/description>zh-cnTue, 17 Jun 2025 08:59:05 GMTTue, 17 Jun 2025 08:59:05 GMT60Java IO 包中的Decorator模式http://www.aygfsteel.com/eric0326/archive/2006/01/10/27349.htmlU狐U狐Tue, 10 Jan 2006 03:16:00 GMThttp://www.aygfsteel.com/eric0326/archive/2006/01/10/27349.htmlhttp://www.aygfsteel.com/eric0326/comments/27349.htmlhttp://www.aygfsteel.com/eric0326/archive/2006/01/10/27349.html#Feedback0http://www.aygfsteel.com/eric0326/comments/commentRss/27349.htmlhttp://www.aygfsteel.com/eric0326/services/trackbacks/27349.html


Java IO 包中的Decorator模式

JDK为程序员提供了大量的cdQ而ؓ了保持类库的可重用性,可扩展性和灉|性,其中使用C大量的设计模式,本文介lJDK的I/O包中使用到的Decorator模式Qƈq用此模式,实现一个新的输出流cR?

  Decorator模式?

  Decorator模式又名包装?Wrapper)Q它的主要用途在于给一个对象动态的d一些额外的职责。与生成子类相比Q它更具有灵zL?br> ? 时候,我们需要ؓ一个对象而不是整个类d一些新的功能,比如Q给一个文本区d一个滚动条的功能。我们可以用承机制来实现q一功能Q但是这U方法不 够灵z,我们无法控制文本区加滚动条的方式和时机。而且当文本区需要添加更多的功能Ӟ比如Ҏ{,需要创建新的类Q而当需要组合用这些功能时无疑会 引vcȝ爆炸?br>
  我们可以使用一U更为灵zȝҎQ就是把文本区嵌入到滚动条中。而这个滚动条的类q当于Ҏ本区的一个装饰。这个装 ?滚动?必须与被装饰的组?文本?l承自同一个接口,q样Q用户就不必兛_装饰的实玎ͼ因ؓq对他们来说是透明的。装C用Lh转发l相? 的组?卌用相关的Ҏ)Qƈ可能在{发的前后做一些额外的动作(如添加滚动条)。通过q种ҎQ我们可以根据组合对文本区嵌套不同的装饰Q从而添加Q 意多的功能。这U动态的对对象添加功能的Ҏ不会引vcȝ爆炸Q也h了更多的灉|性?br>
  以上的方法就是Decorator模式Q它通过l对象添加装饰来动态的d新的功能。如下是Decorator模式的UML图:


Component为组件和装饰的公qc,它定义了子类必须实现的方法?br>
  ConcreteComponent是一个具体的lgc,可以通过l它d装饰来增加新的功能?br>
  Decorator是所有装饰的公共父类Q它定义了所有装饰必d现的ҎQ同Ӟ它还保存了一个对于Component的引用,以便用Lh转发lComponentQƈ可能在{发请求前后执行一些附加的动作?br>
  ConcreteDecoratorA和ConcreteDecoratorB是具体的装饰Q可以用它们来装饰具体的Component?br>
  Java IO包中的Decorator模式

  JDK提供的java.io包中使用了Decorator模式来实现对各种输入输出的装。以下将以java.io.OutputStream及其子类ZQ讨Z下Decorator模式在IO中的使用?br>
  首先来看一D는来创建IO的代码Q?br>

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

   q段代码对于使用qJAVA输入输出的人来说再熟悉不过了,我们使用DataOutputStream装了一个FileOutputStream? q是一个典型的Decorator模式的用,FileOutputStream相当于ComponentQDataOutputStream是一? Decorator。将代码Ҏ如下Q将会更Ҏ理解Q?br>

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

  ׃FileOutputStream和DataOutputStream有公q父类OutputStreamQ因此对对象的装饰对于用h说几乎是透明的。下面就来看看OutputStream及其子类是如何构成Decorator模式的:

OutputStream是一个抽象类Q它是所有输出流的公qc,其源代码如下Q?


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

它定义了write(int b)的抽象方法。这相当于Decorator模式中的ComponentcR?

ByteArrayOutputStreamQFileOutputStream ?PipedOutputStream 三个c都直接从OutputStreaml承Q以ByteArrayOutputStreamZQ?


以下是代码片D:
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;
}
...
}

它实COutputStream中的write(int b)ҎQ因此我们可以用来创出流的对象,q完成特定格式的输出。它相当于Decorator模式中的ConcreteComponentcR?

接着来看一下FilterOutputStreamQ代码如下:


以下是代码片D:
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);
}
...
}

? P它也是从OutputStreaml承。但是,它的构造函数很特别Q需要传递一个OutputStream的引用给它,q且它将保存Ҏ对象的引用? 而如果没有具体的OutputStream对象存在Q我们将无法创徏FilterOutputStream。由于out既可以是指向 FilterOutputStreamcd的引用,也可以是指向ByteArrayOutputStream{具体输出流cȝ引用Q因此用多层嵌套的? 式,我们可以为ByteArrayOutputStreamd多种装饰。这个FilterOutputStreamcȝ当于Decorator模式中的 Decoratorc,它的write(int b)Ҏ只是单的调用了传入的的write(int b)ҎQ而没有做更多的处理,因此它本质上没有Ҏq行装饰Q所以承它的子cd覆盖此ҎQ以辑ֈ装饰的目的?

BufferedOutputStream ? DataOutputStream是FilterOutputStream的两个子c,它们相当于Decorator模式中的 ConcreteDecoratorQƈ对传入的输出做了不同的装饰。以BufferedOutputStreamcMؓ例:


以下是代码片D:
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;
}
...
}



   q个cL供了一个缓存机Ӟ{到~存的容量达C定的字节数时才写入输出流。首先它l承了FilterOutputStreamQƈ且覆盖了父类? write(int b)ҎQ在调用输出写出数据前都会查缓存是否已满,如果未满Q则不写。这样就实现了对输出对象动态的d新功能的目的?br>
  下面Q将使用Decorator模式QؓIO写一个新的输出流?br>
  自己写一个新的输出流

   了解了OutputStream及其子类的结构原理后Q我们可以写一个新的输出流Q来d新的功能。这部分中将l出一个新的输出流的例子,它将qo待输 句中的空格符受比如需要输?java io OutputStream"Q则qo后的输出?javaioOutputStream"。以下ؓSkipSpaceOutputStreamcȝ代码Q?br>

以下是代码片D:
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);
  }
 }
}

  它从FilterOutputStreaml承Qƈ且重写了它的write(int b)Ҏ。在write(int b)Ҏ中首先对输入字符q行了检查,如果不是I格Q则输出?br>
  以下是一个测试程序:


以下是代码片D:
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();
  }
 }
}

  执行以上试E序Q将要求用户在consoleH口中输入信息,E序过滤掉信息中的I格Qƈ最后的l果输出到consoleH口。比如:


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

  ?l?br>
   在java.io包中Q不仅OutputStream用到了Decorator设计模式QInputStreamQReaderQWriter{都用到 了此模式。而作Z个灵zȝQ可扩展的类库,JDK中用了大量的设计模式,比如在Swing包中的MVC模式QRMI中的Proxy模式{等。对? JDK中模式的研究不仅能加深对于模式的理解Q而且q有利于更透彻的了解类库的l构和组成?br>
转自Q?a target="_blank" >http://www.java-cn.com/technology/technology_detail.jsp?id=3976

U狐 2006-01-10 11:16 发表评论
]]>
开始小论文http://www.aygfsteel.com/eric0326/archive/2005/09/17/13247.htmlU狐U狐Sat, 17 Sep 2005 12:38:00 GMThttp://www.aygfsteel.com/eric0326/archive/2005/09/17/13247.htmlhttp://www.aygfsteel.com/eric0326/comments/13247.htmlhttp://www.aygfsteel.com/eric0326/archive/2005/09/17/13247.html#Feedback0http://www.aygfsteel.com/eric0326/comments/commentRss/13247.htmlhttp://www.aygfsteel.com/eric0326/services/trackbacks/13247.html 好久没有来了


U狐 2005-09-17 20:38 发表评论
]]>
回到了西?/title><link>http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.html</link><dc:creator>U狐</dc:creator><author>U狐</author><pubDate>Wed, 24 Aug 2005 10:07:00 GMT</pubDate><guid>http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.html</guid><wfw:comment>http://www.aygfsteel.com/eric0326/comments/10942.html</wfw:comment><comments>http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/eric0326/comments/commentRss/10942.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/eric0326/services/trackbacks/10942.html</trackback:ping><description><![CDATA[<P>回来的感觉真?/P><img src ="http://www.aygfsteel.com/eric0326/aggbug/10942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/eric0326/" target="_blank">U狐</a> 2005-08-24 18:07 <a href="http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank">ʵ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ϲ</a>| <a href="http://" target="_blank">ʩ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ұ</a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank">ƺ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ԫ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Զ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ƽ</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ϳ</a>| <a href="http://" target="_blank">ĩ</a>| <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>