`
vanadiumlin
  • 浏览: 511791 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

责任链过滤器模式

阅读更多
//责任链---要么承担责任作出响应,要么向下传递请求。  
 
//责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心  
缺点: 调试有点小不爽  
 
public class Main {  
 
    public static void main(String[] args) {  
        String msg = "adfasdf,斯蒂芬森的 敏感 >";  
          
        MsgProcessor mp = new MsgProcessor();  
        mp.setMsg(msg);  
        msg = mp.process();  
        System.out.println(msg);  
    }  
 
}  
 
public class MsgProcessor {  
    private String msg;  
      
    /** 
     * 问题:这里的过滤规则会老是被动态的指定 
     * @return 
     */ 
    public String process(){  
            //处理html tag  
        msg = msg.replace("<", "[")  
                 .replace(">", "]");  
          
        //process sensetive word  
        msg = msg.replace("敏感", "**");  
          
        return msg;  
    }  
      
    public String getMsg() {  
        return msg;  
    }  
    public void setMsg(String msg) {  
        this.msg = msg;  
    }  
      
}  
 
/*process里面的流程因需求的不同而不同,所以最好能想要的时候就插上,不想要的时候就拔去,基于这种需求,接口是最好的方式 
*/ 
 
//下面是改进的东西  
 
public interface Filter {  
    String doFilter(String msg);  
}//这相当于一个标准件,是这类东西的接口规则  
 
public class HTMLFilter implements Filter {  
 
    public String doFilter(String msg) {  
          
        //处理html tag  
        msg = msg.replace("<", "[")  
                 .replace(">", "]");  
          
        return msg;  
    }  
 
}//这是一个接口的实现,也就是一个被解耦的外部功能  
 
public class MsgProcessor {  
    private String msg;  
      
    //定义 插座,插座里面当然是放接口的实现,所以改动的地方只有插座  
    Filter[] filters = new Filter[]{new HTMLFilter(),new SensetiveFilter()};  
      
    public String process(){//这个里面就是如何来用这个插座,你可以顺序的用  
          
        for(Filter f : filters){  
            msg = f.doFilter(msg);  
        }  
        return msg;  
    }  
      
    public String getMsg() {  
        return msg;  
    }  
    public void setMsg(String msg) {  
        this.msg = msg;  
    }  
      
}  
 
//再改进,插座升级,原来简单的数组插座,被封装成一个类,并让他更加智能化  
public class FilterChain {  
      
    List<Filter> filters = new ArrayList<Filter>();//数组形式的责任链,他通过一个index来驱动请求向下执行  
      
    public FilterChain add(Filter f){  
        filters.add(f);  
        return this;  //返回this的好处是:可以链式编程  
    }  
      
   public String doFilter(String msg){  
       for(Filter f : filters){  
           f.doFilter(msg);  
       }  
       return msg;  
   }  
      
}  
//注意,这里MsgProcessor是业务逻辑类,不过在这个例子中有些多余,因为业务太简单  
public class Main {  
 
    public static void main(String[] args) {  
        String msg = "adfasdf,操,爱上对方答复 < 敏感 >";  
          
        MsgProcessor mp = new MsgProcessor();  
        mp.setMsg(msg);  
        FilterChain filterChain = new FilterChain();//插座是个类,所以要new 出来  
        filterChain.add(new HTMLFilter())  
                   .add(new SensetiveFilter());  
        msg = mp.process(filterChain);  
        System.out.println(msg);  
    }  
}  
 
/*注意:在我们的生活中,一个插座是可以插到另外一个插座上面去的,这意味着插座也是一个接口的实现,所以我们的FilterChain可以这样 
*/ 
public class FilterChain implements Filter  
 
/* 
需求又要变更了,我们现在的Filter 拥有了两个过滤功能,一个是在消息过去的时候过滤,一个是在消息回来的时候过滤。要求Filter中的两个过滤功能一个第i个位置被调用,一个在第n-i个位置被调用,也就是经过一个来回。。。。。 
怎么办呢,我们想到堆栈的方式,也就是嵌套,把嵌套盒子的左边看成一个过滤网,盒子右边看成一个过滤网,那么嵌套就很形象的解决了这个问题。 
*/ 
public class FilterChain {//因为是数组型责任链,那么他来维护这个index,并导致请求向下传递  
      
    List<Filter> filters = new ArrayList<Filter>();  
    int index = -1;  
    public FilterChain add(Filter f){  
        filters.add(f);  
        return this;  //返回this的好处是:可以链式编程  
    }  
      
   public void doFilter(Request request,Response response,FilterChain fc){  
       filters.get(++index).doFilter(request, response, fc);  
   }      
}//这个插座永远管理着遍历的规则,这里的遍历规则就是遍历下一个  
 
public class SensetiveFilter implements Filter{  
 
    public String doFilter(Request request,Response response,FilterChain fc) {  
        //process sensetive word  
        request.requestStr = request.requestStr.replace("敏感", "**");//---过滤网  
                //下面这句话也可以不写,因为是否驱动向下传递完全取决于你自己  
        fc.doFilter(request, response, fc);//由fc驱动下一个  
        //response dosomething----过滤网  
        return request.requestStr;  
    }  
}  
 
//--------------------------另一个维度来看责任链-------------------------------------------------------------------  
 
来自设计模式之禅  
 
中国古代对妇女制定了“三从四德”的道德规范,“三从”是指“未嫁从父、既嫁从夫、夫死从子”。  
所以我们先定义一个女人类  
public class Women {  
  private int type; //1--未出嫁 2--出嫁 3---夫死  
  private String request = "";  
 
public Women(int type,String request){  
      this.type= type;  
     this.request = request;  
}  
.......setter/getter  
}  
 
夫,父,子都可以出来Women的请求,但请求的方式不同,所以这里拥有方法级别的变量  
public interface IHandler{  
    public void HandlerMessage(IWomen women);  
}  
public class Father implements IHandler{  
    public void HandlerMessage(IWomen women){  
          System.out.println("女儿的请示"+women.getRequest());  
          System.out.println("父亲的答复是:同意");  
    }  
}  
。。。。。。  
 
public class Client{  
   public static void main(String[] args){  
          Random rand = new Random();  
          ArrayList<IWomen> list = new ArrayList();  
          for(int i=0;i<5;i++){  
               list.add(new Women(rand.nextInt(4)),"我要出去逛街");  
          }  
          IHandler father = new Father();  
          IHandler husband = new Hasband();  
          IHandler son = new Som();  
         for(IWomen women:list){  
               if(women.getType() ==1){  
                  System.out.println("----女儿向父亲请示");  
                   father.HandleMessage(women);  
               }else if(women.getType() == 2){  
                    System.out.println("----妻子向丈夫请示");  
                   hasband.HandleMessage(women);  
               }else if(women.getType == 3){  
                      System.out.println("----母亲向儿子请示");  
                      son.HandleMessage(women);  
               }else{  
                    //暂时什么也不做  
               }  
         }  
    }  
}  
 
注意:上面有这么多if..else....显然不怎么好,我们应该把if..else分解到各自的类中,如果不是自己管的范围,那么向下传递,把传递分散到每个类中,而不是想上面一样用一个额外的类来维护。。。filterChain其实也是一个额外维护传递的类哈。。。。  
改进。。。  
 
public abstract class Handler{  
   private int level =0;  
  private Handler nextHandler;  //下一个责任人  
public Handler(int level){  
     this.level = level;  
  }  
  public final void HandlerMessage(IWomen women){ //哈哈,这里是模板方法哈,把算法定死了  
       if(women.getType() == this.level){  
             this.response(women);  
        }else{  
            if(this.nextHandler !=null){  
                   this.nextHandler.HandlerMessage(women);  
            }else{  
                  System.out.println("-------不处理----");  
            }  
        }  
  }  
  //每个相应不同哈  
  public abstract void response(IWomen women);  
}  
 
public class Father extends Handler{  
    public Father(){  
        super(1);  
     }  
 
    public void response(IWomen women){  
         System.out.println("--女儿请示父亲--");  
         System.out.println(women.getRequest());  
         System.out.println("父亲的答复:同意");  
   }  
}  
......  
public class Client{  
   public static void main(String[] args){  
          Random rand = new Random();  
          ArrayList<IWomen> list = new ArrayList();  
          for(int i=0;i<5;i++){  
               list.add(new Women(rand.nextInt(4)),"我要出去逛街");  
          }  
          Handler father = new Father();  
          Handler husband = new Hasband();  
          Handler son = new Som();  
          father.setNext(husband);  
          husband.setNext(son);  
         for(IWomen women:list){  
            father.HandlerMessage(women);  
         }  
    }  
}  
 
经验例子:责任链在实际的项目中使用也是比较多的,我曾经做过这样一个项目,界面上有一个用户注册功能,注册用户分两种,一种是VIP 用户,也就是在该单位办理过业务的,一种是普通用户,一个用户的注册要填写一堆信息,VIP 用户只比普通用户多了一个输入项:VIP 序列号,注册后还需要激活, VIP 和普通用户的激活流程也是不同的,VIP 是自动发送邮件到用户的邮箱中就算激活了,普通用户要发送短信才能激活,为什么呢?获得手机号码以后好发广告短信呀!这个功能项目组就采用了责任链模式,甭管从前台传递过来的是VIP 用户信息还是普通用户信息,统一传递到一个处理入口,通过责任链来完成任务的处理 
分享到:
评论
Global site tag (gtag.js) - Google Analytics