??xml version="1.0" encoding="utf-8" standalone="yes"?>香蒸焦蕉伊在线,婷婷成人影院,飘雪影院手机免费高清版在线观看
http://www.aygfsteel.com/eric0326/java技术,软g工程Q开源相?/description>zh-cn Tue, 17 Jun 2025 08:59:05 GMT Tue, 17 Jun 2025 08:59:05 GMT 60 Java IO 包中的Decorator模式 http://www.aygfsteel.com/eric0326/archive/2006/01/10/27349.htmlU狐 U狐 Tue, 10 Jan 2006 03:16:00 GMT http://www.aygfsteel.com/eric0326/archive/2006/01/10/27349.html http://www.aygfsteel.com/eric0326/comments/27349.html http://www.aygfsteel.com/eric0326/archive/2006/01/10/27349.html#Feedback 0 http://www.aygfsteel.com/eric0326/comments/commentRss/27349.html http://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
]]>开始小论文 http://www.aygfsteel.com/eric0326/archive/2005/09/17/13247.htmlU狐 U狐 Sat, 17 Sep 2005 12:38:00 GMT http://www.aygfsteel.com/eric0326/archive/2005/09/17/13247.html http://www.aygfsteel.com/eric0326/comments/13247.html http://www.aygfsteel.com/eric0326/archive/2005/09/17/13247.html#Feedback 0 http://www.aygfsteel.com/eric0326/comments/commentRss/13247.html http://www.aygfsteel.com/eric0326/services/trackbacks/13247.html 好久没有来了 ]]> 回到了西?/title> http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.htmlU狐 U狐 Wed, 24 Aug 2005 10:07:00 GMT http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.html http://www.aygfsteel.com/eric0326/comments/10942.html http://www.aygfsteel.com/eric0326/archive/2005/08/24/10942.html#Feedback 0 http://www.aygfsteel.com/eric0326/comments/commentRss/10942.html http://www.aygfsteel.com/eric0326/services/trackbacks/10942.html 回来的感觉真?/P> ]]>
վ֩ģ壺
̨ |
ʵ |
|
|
|
|
|
ϲ |
ʩ |
|
|
|
Ұ |
˳ |
ƺ |
|
|
|
|
|
|
Ԫ |
|
|
Զ |
|
|
|
|
ƽ |
ɽ |
|
Ϳ |
ĩ |
̨ |
ʡ |
|
˳ |
|
|
|