我在wikipedia读过,Decorator模式用于.Net和Java IO类.
任何人都能解释一下这是如何使用的吗?它有一个可能的例子,有什么好处?
*上有一个Windows窗体的例子,但我想知道Java IO类是如何发生的.
解决方法:
InputStream
是一个抽象类.大多数具体实现(如BufferedInputStream
,GzipInputStream
,ObjectInputStream
等)都有一个构造函数,它接受相同抽象类的实例.这是装饰器模式的识别键(这也适用于采用相同接口实例的构造函数).
当使用这样的构造函数时,所有方法都将委托给包装的实例,并改变方法的行为方式.例如,事先在内存中缓冲流,预先解压缩流或以不同方式解释流.有些甚至还有其他方法最终也会进一步委托给包装的实例.这些方法用额外的行为装饰包装的实例.
假设我们在Gzip文件中有一堆序列化的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();
也可以看看:
> Examples of GoF Design Patterns in Java’s core libraries