本篇随笔主要介绍用Java实现简单的装饰器设计模式:
先来看一下装饰器设计模式的类图:
从图中可以看到,我们可以装饰Component接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可以再被装饰。
下面是用Java实现的简单的装饰器设计模式,提供的是从基本的加入咖啡入手,可以继续加入牛奶,巧克力,糖的装饰器系统。
1 interfaceComponent {2 voidmethod();3 }4 class Coffee implementsComponent {5
6 @Override7 public voidmethod() {8 //TODO Auto-generated method stub
9 System.out.println("倒入咖啡");10 }11
12 }13 class Decorator implementsComponent {14 publicComponent comp;15 publicDecorator(Component comp) {16 this.comp =comp;17 }18 @Override19 public voidmethod() {20 //TODO Auto-generated method stub
21 comp.method();22 }23
24 }25 class ConcreteDecorateA extendsDecorator {26 publicComponent comp;27 publicConcreteDecorateA(Component comp) {28 super(comp);29 this.comp =comp;30 }31 public voidmethod1() {32 System.out.println("倒入牛奶");33 }34 public voidmethod2() {35 System.out.println("加入糖 ");36 }37 public voidmethod() {38 super.method();39 method1();40 method2();41 }42 }43 class ConcreteDecorateB extendsDecorator {44 publicComponent comp;45 publicConcreteDecorateB(Component comp) {46 super(comp);47 this.comp =comp;48 }49 public voidmethod1() {50 System.out.println("加入巧克力");51 }52 public voidmethod() {53 super.method();54 method1();55 }56 }57 public classTestDecoratePattern {58 public static voidmain(String[] args) {59 Component comp = newCoffee();60 comp.method();61 System.out.println("--------------------------------------------------");62 Component comp1 = newConcreteDecorateA(comp);63 comp1.method();64 System.out.println("--------------------------------------------------");65 Component comp2 = newConcreteDecorateB(comp1);66 comp2.method();67 System.out.println("--------------------------------------------------");68 Component comp3 = new ConcreteDecorateB(new ConcreteDecorateA(newCoffee()));69 comp3.method();70 System.out.println("--------------------------------------------------");71 Component comp4 = new ConcreteDecorateA(new ConcreteDecorateB(newCoffee()));72 comp4.method();73 }74 }
运行结果:
装饰器设计模式可以使得我们自由的,以任意顺序导入巧克力,牛奶,咖啡和糖。可以实现多层,任意顺序的装饰。
Java中实际应用举例:
1、java io流
以下一句代码即体现了装饰器设计模式的应用:
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(new File(filePath), true)));
PrintWriter类及BufferedWriter类就相当于上面装饰器设计模式类图中的ConcreteDecorateA 与 ConcreteDecorateB,FileWriter类则相当于上面类图中的ConcreteComponent类,PrintWriter类的构造器实际接受的是一个Writer类的对象,在这里即为BufferedWriter类的对象,然后对这个Writer类的write方法进行装饰。
2、web应用中在filter类中实现自定义的输入输出
filter类实现如下:
public class AllFilter implementsFilter {
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {
}
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {//自定义输出流
ServletResponse compressionResponse = newCompressionResponseWrapper((HttpServletResponse) servletResponse);//把自定义的输出流传递到用户实现的servlet中去
filterChain.doFilter(servletRequest, compressionResponse);
}
@Overridepublic voiddestroy() {
}
}
其中自定义的输出流 CompressionResponseWrapper 类就是装饰器设计模式的一个应用。CompressionResponseWrapper类实现如下:
public class CompressionResponseWrapper extendsHttpServletResponseWrapper {privateHttpServletResponse response;publicCompressionResponseWrapper(HttpServletResponse response) {super(response);this.response =response;
}
@Overridepublic ServletOutputStream getOutputStream() throwsIOException {
System.out.println("在这里可对输出流进行定制操作,例如进行压缩,返回压缩后的新的输出流");returnresponse.getOutputStream();
}
}
这里CompressionResponseWrapper类相当于上述装饰器设计模式类图中的ConcreteDecorateA类,HttpServletResponse类则相当于待装饰的接口。CompressionResponseWrapper类还可以再被装饰添加其他功能,这就是装饰器设计模式的强大之处。