装饰器设计模式初探及Java中实际应用举例

  本篇随笔主要介绍用Java实现简单的装饰器设计模式:

    先来看一下装饰器设计模式的类图:

    

     从图中可以看到,我们可以装饰Component接口的任何实现类,而这些实现类也包括了装饰器本身,装饰器本身也可以再被装饰。

 

    下面是用Java实现的简单的装饰器设计模式,提供的是从基本的加入咖啡入手,可以继续加入牛奶,巧克力,糖的装饰器系统。

    

 1 interface Component {
 2     void method();
 3 }
 4 class Coffee implements Component {
 5 
 6     @Override
 7     public void method() {
 8         // TODO Auto-generated method stub
 9         System.out.println("倒入咖啡");
10     }
11     
12 }
13 class Decorator implements Component {
14     public Component comp;
15     public Decorator(Component comp) {
16         this.comp = comp;
17     }
18     @Override
19     public void method() {
20         // TODO Auto-generated method stub
21         comp.method();
22     }
23     
24 }
25 class ConcreteDecorateA extends Decorator {
26     public Component comp;
27     public ConcreteDecorateA(Component comp) {
28         super(comp);
29         this.comp = comp;
30     }
31     public void method1() {
32         System.out.println("倒入牛奶");
33     }
34     public void method2() {
35         System.out.println("加入糖 ");
36     }
37     public void method() {
38         super.method();
39         method1();
40         method2();
41     }
42 }
43 class ConcreteDecorateB extends Decorator {
44     public Component comp;
45     public ConcreteDecorateB(Component comp) {
46         super(comp);
47         this.comp = comp;
48     }
49     public void method1() {
50         System.out.println("加入巧克力");
51     }
52     public void method() {
53         super.method();
54         method1();
55     }
56 }
57 public class TestDecoratePattern {
58     public static void main(String[] args) {
59         Component comp = new Coffee();
60         comp.method();
61         System.out.println("--------------------------------------------------");
62         Component comp1 = new ConcreteDecorateA(comp);
63         comp1.method();
64         System.out.println("--------------------------------------------------");
65         Component comp2 = new ConcreteDecorateB(comp1);
66         comp2.method();
67         System.out.println("--------------------------------------------------");
68         Component comp3 = new ConcreteDecorateB(new ConcreteDecorateA(new Coffee()));
69         comp3.method();
70         System.out.println("--------------------------------------------------");
71         Component comp4 = new ConcreteDecorateA(new ConcreteDecorateB(new Coffee()));
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 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {     
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //自定义输出流
        ServletResponse compressionResponse = new CompressionResponseWrapper((HttpServletResponse) servletResponse);

     //把自定义的输出流传递到用户实现的servlet中去
        filterChain.doFilter(servletRequest, compressionResponse);
       
    }

    @Override
    public void destroy() {
    }
}

  其中自定义的输出流 CompressionResponseWrapper 类就是装饰器设计模式的一个应用。CompressionResponseWrapper类实现如下:  

public class CompressionResponseWrapper extends HttpServletResponseWrapper {
    private HttpServletResponse response;
    public CompressionResponseWrapper(HttpServletResponse response) {
        super(response);
        this.response = response;
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        System.out.println("在这里可对输出流进行定制操作,例如进行压缩,返回压缩后的新的输出流");
        return response.getOutputStream(); 
   }
}

  这里CompressionResponseWrapper类相当于上述装饰器设计模式类图中的ConcreteDecorateA类,HttpServletResponse类则相当于待装饰的接口。CompressionResponseWrapper类还可以再被装饰添加其他功能,这就是装饰器设计模式的强大之处。


posted @ 2016-09-18 19:54  Michaelwjw  阅读(1875)  评论(0编辑  收藏  举报