IO 的 GoF 装饰器模式的用例和示例
我在维基百科中读到,装饰器模式用于.Net和Java IO类。
任何人都可以解释这是如何使用的吗?用一个可能的例子来说,它有什么好处?
维基百科上有一个Windows表单的例子,但我想知道Java IO类是如何发生的。
我在维基百科中读到,装饰器模式用于.Net和Java IO类。
任何人都可以解释这是如何使用的吗?用一个可能的例子来说,它有什么好处?
维基百科上有一个Windows表单的例子,但我想知道Java IO类是如何发生的。
InputStream
是一个抽象类。大多数具体的实现,如BufferedInputStream
,GzipInputStream
,ObjectInputStream
等,都有一个构造函数,该构造函数采用同一抽象类的实例。这是装饰器模式的识别键(这也适用于采用相同接口实例的构造函数)。
使用此类构造函数时,所有方法都将委托给包装的实例,并更改方法的行为方式。例如,事先在内存中缓冲流、事先解压缩流或以不同的方式解释流。有些甚至有其他方法,这些方法最终还会进一步委托给包装的实例。这些方法使用额外的行为来修饰包装的实例。
假设我们在Gzipped文件中有一堆序列化的Java对象,并且我们希望快速读取它们。
首先打开它的输入流:
FileInputStream fis = new FileInputStream("/objects.gz");
我们想要速度,所以让我们在内存中缓冲它:
BufferedInputStream bis = new BufferedInputStream(fis);
该文件已 gzip,因此我们需要将其解压缩:
GzipInputStream gis = new GzipInputStream(bis);
我们需要取消序列化这些 Java 对象:
ObjectInputStream ois = new ObjectInputStream(gis);
现在我们终于可以使用它了:
SomeObject someObject = (SomeObject) ois.readObject();
// ...
好处是,您可以使用一个或多个不同的装饰器来装饰流,以满足您的需求。这比为每个可能的组合(如、等)使用单个类要好得多。ObjectGzipBufferedFileInputStream
ObjectBufferedFileInputStream
GzipBufferedFileInputStream
ObjectGzipFileInputStream
ObjectFileInputStream
GzipFileInputStream
BufferedFileInputStream
请注意,当您要关闭流时,只需关闭最外层的装饰器就足够了。它将把关闭调用一直委托到底部。
ois.close();
让我们在介绍 java IO 类之前了解 Decorator 模式的组件。
装饰器图案有四个组成部分
装饰器模式可用于静态扩展(装饰)某个对象的功能,或者在某些情况下在运行时独立于同一类的其他实例,前提是在设计时完成一些基础工作。这是通过设计一个包装原始类的新 Decorator 类来实现的。
现在,让我们将这些概念映射到 java.io pacakge 类。
元件:
输入流 :
此抽象类是表示字节输入流的所有类的超类。
需要定义 InputStream 子类的应用程序必须始终提供返回下一个输入字节的方法。
public abstract int read()
是一种抽象方法。
混凝土组件:
FileInputStream 从文件系统中的文件获取输入字节。哪些文件可用取决于主机环境。
FileInputStream 用于读取原始字节流,例如图像数据。要读取字符流,请考虑使用 FileReader。
输入流的所有混凝土组件的示例:
AudioInputStream, ByteArrayInputStream, FileInputStream, FilterInputStream,
InputStream, ObjectInputStream, PipedInputStream, SequenceInputStream,
StringBufferInputStream
装饰:
FilterInputStream 包含一些其他输入流,它使用这些输入流作为其基本数据源,可能会在此过程中转换数据或提供其他功能。
请注意,实现 =>装饰器实现组件,如 UML 图所示。FilterInputStream
InputStream
public class FilterInputStream
extends InputStream
混凝土装饰:
BufferedInputStream 向另一个输入流添加功能,即缓冲输入以及支持标记和重置方法的功能。
所有混凝土装饰器的示例:
BufferedInputStream, CheckedInputStream, CipherInputStream, DataInputStream,
DeflaterInputStream, DigestInputStream, InflaterInputStream,
LineNumberInputStream, ProgressMonitorInputStream, PushbackInputStream
工作示例代码:
我曾经读过一个单词的每个字符,它都存储在一个文本文件中.txtBufferedInputStream
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
while(bis.available()>0)
{
char c = (char)bis.read();
System.out.println("Char: "+c);;
}
何时使用此模式: