拦截过滤器模式

拦截过滤器模式


拦截过滤器模式:允许开发人员通过不同的标准,过滤一组对象,通过逻辑操作把他们以解耦的方式把他们连接起来,他可以组合多个标准来获得单一标准。在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 中存在上一次中的数据。

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

猜你喜欢

转载自blog.csdn.net/qq_35133320/article/details/77900328