设计模式——责任链模式

使用场景: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中的拦截器就是应用责任链模式

相关文章
相关标签/搜索