裝飾器設計模式初探及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類還可以再被裝飾添加其他功能,這就是裝飾器設計模式的強大之處。

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM