我在维基百科中已经读到Decorator模式用于.Net和Java IO类。
有人可以解释如何使用吗?举一个可能的例子,它的好处是什么?
维基百科上有一个Windows表单示例,但我想知道Java IO类如何发生这种情况。
InputStream是一个抽象类。最具体的实现比如BufferedInputStream,GzipInputStream,ObjectInputStream等有一个构造函数中的一个实例相同的抽象类。这是装饰器模式的识别键(这也适用于采用相同接口实例的构造函数)。
InputStream
BufferedInputStream
GzipInputStream
ObjectInputStream
使用此类构造函数时,所有方法都将委派给包装的实例,并改变方法的行为方式。例如,预先在内存中缓冲流,预先对流进行解压缩或对流进行不同的解释。有些甚至具有其他方法,这些方法最终也进一步委托给包装的实例。这些方法用额外的行为来修饰包装的实例。
假设我们在Gzipped文件中有一堆序列化的Java对象,并且我们想快速读取它们。
首先打开它的输入流:
FileInputStream fis = new FileInputStream("/objects.gz");
我们需要速度,因此让我们将其缓冲在内存中:
BufferedInputStream bis = new BufferedInputStream(fis);
该文件已压缩,因此我们需要将其解压缩:
GzipInputStream gis = new GzipInputStream(bis);
我们需要反序列化那些Java对象:
ObjectInputStream ois = new ObjectInputStream(gis);
现在我们终于可以使用它了:
SomeObject someObject = (SomeObject) ois.readObject(); // ...
好处是你可以自由使用一个或多个各种装饰器来装饰流,以满足你的需求。这比具有每一个可能的组合就像一个类好得多ObjectGzipBufferedFileInputStream,ObjectBufferedFileInputStream,GzipBufferedFileInputStream,ObjectGzipFileInputStream,ObjectFileInputStream,GzipFileInputStream,BufferedFileInputStream,等。
ObjectGzipBufferedFileInputStream,ObjectBufferedFileInputStream,GzipBufferedFileInputStream,ObjectGzipFileInputStream,ObjectFileInputStream,GzipFileInputStream,BufferedFileInputStream
请注意,当你要关闭流时,仅关闭最外面的装饰器就足够了。它将把关闭调用一直委托给底部。
ois.close();