拦截过滤器模式

来源:互联网 发布:学会计的软件 编辑:程序博客网 时间:2024/05/18 02:25

拦截过滤器模式


拦截过滤器模式:允许开发人员通过不同的标准,过滤一组对象,通过逻辑操作把他们以解耦的方式把他们连接起来,他可以组合多个标准来获得单一标准。在Java web中主要用于统一接收并过滤客户端的请求,根据过滤器的选择,将请求传送给对应目标处理程序。

场景

现有一段文字,按要求过滤将文符过滤出来
例如:

 输入:"5UCHoddo&+Qo4.~*cQ" 过滤字母输出:"5&+4.~*" 过滤数字输出:"UCHoddo&+Qo.~*cQ" 过滤字符输出:"5UCHoddoQo4cQ"

实现

IFilter:接口,用于统一的过滤标准
XXXFilterImpl:IFilter的实现类,用于IFilter中方法的具体实现
FilterManager:用于管理多个过滤器
deo:演示类

目录结构

包结构

过滤接口

  • IFilter.java
public interface IFilter {    String doFilter(String content); }

具体实现类

  • LetterFilterImpl.java
/** * 具体的过滤类,用于过滤字母a~z,A~Z * @author admian * */public class LetterFilterImpl implements IFilter {    private String letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";    @Override    public String doFilter(String content) {        StringBuffer sb = new StringBuffer();        char[] cs = content.toCharArray();        for (char c : cs) {            if (!letter.contains((c + "").toUpperCase())) {                sb.append(c);            }        }        return new String(sb);    }}
  • NumberFilterImpl .java
/** * 具体的过滤类,用于过滤数字0~9 * @author admian * */public class NumberFilterImpl implements IFilter {    private String number = "0123456789";     @Override    public String doFilter(String content) {        StringBuffer sb = new StringBuffer();        char[] cs = content.toCharArray();        for (char c : cs) {            if (!number.contains(c + "")) {                sb.append(c);            }        }        return new String(sb);    }}
  • CharFilterImpl.java
/** * 具体的过滤类,用于过滤非数字0~9和非字母a~z,A~Z * @author admian * */public class CharFilterImpl implements IFilter {    private String letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";    private String number = "0123456789";    @Override    public String doFilter(String content) {        StringBuffer sb = new StringBuffer();        char[] cs = content.toCharArray();        for (int i = 0; i < cs.length; i++) {            if (letter.contains((cs[i] + "").toUpperCase()) && number.contains(cs[i] + "")) {                sb.append(cs[i]);            }        }        return new String(sb);    }}

过滤器管理类

  • FilterManager.java
public class FilterManager {    List<IFilter> filters = new LinkedList<>();    public void addFilter(IFilter filter) {        filters.add(filter);    }    public String excute(String content) {        for (IFilter filter : filters) {            content = filter.doFilter(content);        }        return content;    }    public void excuteRemove(IFilter filter) {         filters.remove(filter);    }}

过滤器演示类

  • deo.java
public class deo {    public static void main(String[] args) {        String content = "5UCHoddo&+Qo4.~*cQ";        FilterManager manager = new FilterManager();        LetterFilterImpl f1 = new LetterFilterImpl();        NumberFilterImpl f2 = new NumberFilterImpl();        CharFilterImpl f3 = new CharFilterImpl();        manager.addFilter(f1);        manager.addFilter(f2);         manager.addFilter(f3);        String s1 = manager.excute(content);          System.out.println("过滤字母、数字、字符:"+s1);        manager.excuteRemove(f3);        String s2 = manager.excute(content);          System.out.println("过滤字母、数字:"+s2);        manager.excuteRemove(f2);        String s3 = manager.excute(content);          System.out.println("过滤字母:"+s3);        manager.excuteRemove(f1);        String s4 = manager.excute(content);          System.out.println("无过滤:"+s4);    }}

结果:

过滤字母、数字、字符:过滤字母、数字:&+.~*过滤字母:5&+4.~*过滤字母:5UCHoddo&+Qo4.~*cQ

通过新的语言特性,我们可以简化设计模式的使用,更快速的开发程序。这是简单的过滤器模式希望不足,有什么请大家多多指教

总结

在写实现类的时候将* StringBuffer sb = new StringBuffer(); 写在了IFilter接口中实现类方法doFilter()的外面,作为为全局变量。当时觉得没有什么错误,但是在运行的时候发现结果总是会多一遍字符串,如输入 “5UCHoddo&+Qo4.~*cQ” 要求过滤字母和数字结果会输出 “&+.~&+.~*” **。

我在想是不是我哪里错了?就那么多类,我首先想到是FilterManager方法中的excute() 方法在运行过程中多运行了几次或者是变量传递出现错误,然后在 excute() for 循环前后各加了打印变量的值 如图:

可以看出是这里出的错,但是不知道是不是方法中调用 doFilter() 的时候是否有错,接着我又在 NumberFilterImpl 类中加入打印并将 FilterManager 中的打印注释,如图:

经过以上种种分析,问题就在 StringBuffer 中那么问题出在哪里,这时我想起StringBuffer中具有缓存功能,是不是缓存???可能是,那么每次调用 doFilter() 的时候我们把他清空,结果是对的。但是真的是缓存的原因么???再仔细回想看 deo 类中写的,发现我们在每一次调用 excuteRemove() 方法的时候在调用实现类 doFilter() 方法的时候使用的 StringBuffer 是全局变量,存在于这个类的起始,所以我们使用 StringBuffer 的 append() 方法的时候有可能 StringBuffer 中存在上一次中的数据。

如果有不同意见请多多指教!

原创粉丝点击