该模式在java中比较典型的应用也就是jdk的io系统了
装饰模式类图
好吧,其实这类图只对UML熟悉的人才有用,装饰模式有啥用?说白了就是在原来类的功能上,对这些功能做一些增强处理,当然为了增强功能而通过继承也是一种有效的方式,当然对于各种组合比较多的情况下,使用继承可能会有太多的类出现,所以就需要使用装饰模式,当然装饰模式的缺点也是显而易见的,使用上会比较麻烦。
举个例子:
FileReader
StringReader
我要为这两个类的read功能增加缓存功能,如果使用继承方式,我需要两个子类来完成,也许这两个子类得叫BufferedFileReader和BufferedFileStringReader,如果要增加缓存功能的类有十个,那么子类也就需要十个,但是如果用装饰模式,我只要增加一个装饰类既可满足,BufferedReader类,这个就是jdk1.1的io系统设计。
普通的装饰模式简单示例
套用io模式的BufferedReader,StringReader,Reader的read功能来做说明:
首先来说明这三个类在上述类图的位置:
Reader:Compoent也是Decorator的基础类
StringReader:ConcreateComponent
BufferedReader:ConcreateDecoratorA
写出简略代码,从jdk1.1中的源码抠出来,去除了很多与该模式无关的代码:
从上面可以看出,BufferedReader类其实就是将Reader的子类(ConcreateComponent)也就是这里的StingReader的数据放入缓存,然后操作read方法的时候,从缓存中读取,但是实际上的流还是通过StringReader来获取的。也就是说BufferedReader对StringReader类的read功能增加了缓存功能,在事实上,你不使用BufferedReader也可以直接操作StringReader的read功能,只是没有了缓存效果而已。
客户端使用的代码:
String s = "This is the/n/ninternal StringReader buffer./ndderwe";
StringReader stringReader = new StringReader(s);
BufferedReader bufReader = new BufferedReader(stringReader);
可以看到,客户端使用是比较麻烦的,这就是装饰模式的缺点。