設計模式——責任鏈模式

使用場景:java

如今有以下字符     :) English < > ,如今想把其轉換爲  ^V^ 英文 [],而且根據要求對  :) English  < >  這三類字符分別轉換web

解決辦法:編程

(1)if else進行處理,低級的辦法,很少說。服務器

(2)定義一個Filter接口,而後在定義三個實現Filter的類,根據具體的需求定義一個FilterChain。類圖以下:測試

//注意:addFilter(Filter)返回值是 FilterChain,這是爲了方便後面的鏈式編程this

場景:若是實現Filter接口的多個類要組合成一個總體使用。spa

解決辦法:將這幾個類組合成爲一個FilterChian,同時FilterChain繼承Filter接口code


具體代碼:orm

//Filter接口
public interface Filter {
   String doFilter(String str);
}

//實現Filter接口的類
public class EnglishFilter implements Filter {
   public String doFilter(String str) {
      String r = str.replace("English", "英文");
      return r;
   }
}


public class FaceFilter implements Filter {

   public String doFilter(String str) {
      return str.replace(":)", "^V^");
   }
}

public class HTMLFilter implements Filter {

   public String doFilter(String str) {
      String r = str.replace('<', '[')
               .replace('>', ']');
      return r;
   }
}

//FilterChain(對FilterChain中的Filter以此進行處理)
public class FilterChain implements Filter {
   List<Filter> filters = new ArrayList<Filter>();
   
   public FilterChain addFilter(Filter f) {
      this.filters.add(f);
      return this;
   }
   
   public String doFilter(String str) {
      String r = str;
      for(Filter f: filters) {
         r = f.doFilter(r);
      }
      return r;
   }
}

//處理流程的分裝,只須要傳入處理的數據,和調用的FilterChain
public class MsgProcessor {
    
   //省略setter,getter方法
   private String msg;
   FilterChain fc;
   
   public String process() {
      return fc.doFilter(msg);
   }
}

//測試方法
public static void main(String[] args) {
   //須要處理的數據
   String msg = ":) English < >";
   //定義初始化處理的方法
   MsgProcessor mp = new MsgProcessor();
   //傳入數據
   mp.setMsg(msg);
   //定義初始化FilterChain
   FilterChain fc = new FilterChain();
   //這裏即是addFilter(Filter)返回值是 FilterChain好處
   fc.addFilter(new HTMLFilter())
     .addFilter(new EnglishFilter());

   FilterChain fc2 = new FilterChain();
   fc2.addFilter(new FaceFilter());
   //將這幾個實現Filter接口的類組合成爲一個FilterChian,添加到另外一個FilterChain中
   fc.addFilter(fc2);
   //傳入FilterChain
   mp.setFc(fc);
   String result = mp.process();
   System.out.println(result);
}

上面只是一個簡單的Filter,對於web中request和response都須要攔截的攔截器該如何編寫呢?
繼承

注意區別:上面的是一條直鏈

 web中的鏈條還要折回來,而且response處理的順序和request的順序相反。

解決辦法:doFilter(request,response,filterChain),多加一個filterChain參數


具體代碼

//客戶端
public class Request {
   //省略getter setter方法
   String requestStr;
}

//服務器端
public class Response {
   //省略getter setter方法
   String responseStr;
}

//Filter接口(注意多了一個chain參數)
public interface Filter {
   void doFilter(Request request, Response response, FilterChain chain);
}

//Filter接口的實現類
public class HTMLFilter implements Filter {

   public void doFilter(Request request, Response response, FilterChain chain) {
      request.requestStr = request.requestStr.replace('<', '[')
               .replace('>', ']') + "---HTMLFilter()";
      //調用下一個Filter
      chain.doFilter(request, response, chain);
      //等調完成執行
      response.responseStr = response.getResponseStr().replace('[', '<')
            .replace(']', '>') + "---HTMLFilter()";
   }

}



public class EnglishFilter implements Filter {

   public void doFilter(Request request, Response response, FilterChain chain) {
      request.requestStr = request.requestStr.replace("English", "英文") + "---EnglishFilter()";
      chain.doFilter(request, response, chain);
      response.responseStr = response.getResponseStr().replace("英文", "English")+"---EnglishFilter()";
   }
}

//FilterChain,FIlter的執行
public class FilterChain implements Filter {
   List<Filter> filters = new ArrayList<Filter>();
   int index = 0;
   
   public FilterChain addFilter(Filter f) {
      this.filters.add(f);
      return this;
   }
   
   //遞歸調用
   public void doFilter(Request request, Response response, FilterChain chain) {
      if(index == filters.size()) return ;
      
      Filter f = filters.get(index);
      index ++;
      f.doFilter(request, response, chain);
   }
}

public static void main(String[] args) {
   String msg = "< > English";
   Request request = new Request();
   //客戶端設置須要處理的String
   request.setRequestStr(msg);
   Response response = new Response();
   //講客戶端處理好的參數賦給服務器端
   response.setResponseStr(request.getRequestStr());
   //FilterChain中添加Filter
   FilterChain fc = new FilterChain();
   fc.addFilter(new HTMLFilter())
     .addFilter(new EnglishFilter());
   //執行FilterChain
   fc.doFilter(request, response, fc);
   System.out.println(request.getRequestStr());
   System.out.println();
   System.out.println(response.getResponseStr());
}

執行結果:

[ ] 英文---HTMLFilter()---EnglishFilter()

< > English---EnglishFilter()---HTMLFilter()

應用:truts2中的攔截器就是應用責任鏈模式

相關文章
相關標籤/搜索