小编典典

Java IO的GoF装饰器模式的用例和示例

java

我在维基百科中已经读到Decorator模式用于.Net和Java IO类。

有人可以解释如何使用吗?举一个可能的例子,它的好处是什么?

维基百科上有一个Windows表单示例,但我想知道Java IO类如何发生这种情况。


阅读 294

收藏
2020-03-15

共1个答案

小编典典

InputStream是一个抽象类。最具体的实现比如BufferedInputStreamGzipInputStreamObjectInputStream等有一个构造函数中的一个实例相同的抽象类。这是装饰器模式的识别键(这也适用于采用相同接口实例的构造函数)。

使用此类构造函数时,所有方法都将委派给包装的实例,并改变方法的行为方式。例如,预先在内存中缓冲流,预先对流进行解压缩或对流进行不同的解释。有些甚至具有其他方法,这些方法最终也进一步委托给包装的实例。这些方法用额外的行为来修饰包装的实例。

假设我们在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,等。

请注意,当你要关闭流时,仅关闭最外面的装饰器就足够了。它将把关闭调用一直委托给底部。

ois.close();
2020-03-15