过滤器模式:将多个互不耦合的标准组成连接成一个标准。若没使用过滤器模式的话,我们如果需要根据不同场景将数据根据不同条件去过滤,那么我们需要在一个类中编写一大串的if-else 代码,而且不同场景的逻辑代码耦合在同一个类中,不利于代码维护,以及代码复用。倘若每个场景分别对应一个类,生成标准可以以注册的形式添加,代码复用性更高。
很多框架用到过滤器模式,如tomcat的Filter,Druid数据统计的Filter。感兴趣的同学可以去去看下。
下面是自己编写的用例,加深过滤器模式的理解。
首先创建Filter和FilterChain接口,表明过滤器和过滤链具备哪些功能。
public interface Filter {
List<FilterDemo> doFilter(List<FilterDemo> filterDemo, FilterChain filterChain);
}public interface FilterChain {
List<FilterDemo> doFilter(List<FilterDemo> filterDemos);
}接着编写Filter的实现类。
根据名字过滤
public class NameFilter implements Filter {
private static final String TARGET_NAME = "filter";
@Override
public List<FilterDemo> doFilter(List<FilterDemo> filterDemo, FilterChain filterChain) {
FilterDemo temp;
Iterator<FilterDemo> iterator = filterDemo.iterator();
while (iterator.hasNext()) {
temp = iterator.next();
if (TARGET_NAME.equals(temp.getName())) {
iterator.remove();
}
}
return filterChain.doFilter(filterDemo);
}
}根据性别过滤
public class SexFilter implements Filter {
private static final String SEX = "man";
@Override
public List<FilterDemo> doFilter(List<FilterDemo> filterDemo, FilterChain filterChain) {
FilterDemo temp;
Iterator<FilterDemo> iterator = filterDemo.iterator();
while (iterator.hasNext()) {
temp = iterator.next();
if (SEX.equals(temp.getSex())) {
iterator.remove();
}
}
return filterChain.doFilter(filterDemo);
}
}根据年龄过滤
public class AgeFilter implements Filter {
private static final Integer AGE = 10;
@Override
public List<FilterDemo> doFilter(List<FilterDemo> filterDemo, FilterChain filterChain) {
FilterDemo temp;
Iterator<FilterDemo> iterator = filterDemo.iterator();
while (iterator.hasNext()) {
temp = iterator.next();
if (AGE.equals(temp.getAge())) {
iterator.remove();
}
}
return filterChain.doFilter(filterDemo);
}
}过滤对象
public class FilterDemo {
private String name;
private Integer age;
private String sex;
public FilterDemo(String name, Integer age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
//set() get() toString() ...
}最后是过滤链实现
public class FilterChainImp implements FilterChain {
private List<Filter> filters;//注册的过滤器
private static int size;//过滤器数
private static int currentSize = 0;//当前执行的过滤器位置
public FilterChainImp(List<Filter> filters) {
this.filters = filters;
size = filters.size();
}
@Override
public List<FilterDemo> doFilter(List<FilterDemo> filterDemos) {
if (currentSize < size) {
filterDemos = filters.get(currentSize++).doFilter(filterDemos, this);
}
return filterDemos;
}
}最后写个main方法跑下
public class FilterPattern {
public static void main(String[] args) {
Filter nameFilter = new NameFilter();
Filter ageFilter = new AgeFilter();
Filter sexFilter = new SexFilter();
List<Filter> filterList = new ArrayList<>(4);
filterList.add(nameFilter);
filterList.add(ageFilter);
filterList.add(sexFilter);
FilterChain filterChain = new FilterChainImp(filterList);
FilterDemo demo1 = new FilterDemo("filter", 11, "woman");
FilterDemo demo2 = new FilterDemo("one", 10, "woman");
FilterDemo demo3 = new FilterDemo("two", 12, "man");
FilterDemo demo4 = new FilterDemo("three", 13, "woman");
List<FilterDemo> demos = new ArrayList<>(4);
demos.add(demo1);
demos.add(demo2);
demos.add(demo3);
demos.add(demo4);
List<FilterDemo> result = filterChain.doFilter(demos);
for (FilterDemo filterDemo : result) {
System.out.println(filterDemo.toString());
}
}
}最后输出结果:FilterDemo{name='three', age=13, sex='woman'}通过案例,使用过滤器我们可以根据不同的条件去选择过滤器,过滤器也可以各自组合,不必相同的代码不断被复制。
个人见解:过滤器模式核心逻辑在于调用过滤器时,过滤链(FilterChain)当做参数传入,当走完一个过滤器后继续调用过滤链的过滤方法执行下一个过滤器,直至过滤器全都走完。
看完当前案例回头再去tomcat的过滤器,相信能帮助你更好的理解它的工作机制。
(扫码关注公众号)
注:基于水平限制,文档只是对于自己的提升,有出入请指教。(未经授权禁转)