一套过滤器,让你的代码高处不胜寒!

2022-12-02 20:04:58 浏览数 (2)

一、介绍

过滤器模式,顾名思义,从名字上就可以看出主要用于过滤对象,实现起来也很简单!

从设计的角度看,过滤器模式涉及到三个角色:

  • 抽象过滤器角色:主要定义过滤器的行为;
  • 具体滤器角色:实现或者继承抽象过滤器,完善具体算法;
  • 客户端:客户类提出使用具体类的请求;

话不多说,代码直接撸起来~

二、示例

下面,我们以班级同学为例,过滤出满足要求的同学,实现过程如下!

先创建一个数据实体类Person,如下:

代码语言:javascript复制
/**
 * 数据实体类
 */
public class Person {

    private String name;//姓名

    private String gender;//性别

    private int age;//年龄


    public String getName() {
        return name;
    }

    //...省略set/get

    public Person(String name, String gender, int age) {
        this.name = name;
        this.gender = gender;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{"  
                "name='"   name   '''  
                ", gender='"   gender   '''  
                ", age="   age  
                '}';
    }
}

然后,创建一个过滤器标准接口Filter,代码如下:

代码语言:javascript复制
/**
 * 过滤器接口
 */
public interface Filter {

    /**
     * 过滤操作
     * @param personList
     * @return
     */
    List<Person> filterOperate(List<Person> personList);
}

接着,创建过滤器具体实现类AgeFilterGenderFilter,代码如下:

代码语言:javascript复制
/**
 * 过滤已满足18岁的同学
 */
public class AgeFilter implements Filter {

    @Override
    public List<Person> filterOperate(List<Person> personList) {
        List<Person> targetList = new ArrayList<>();
        for (Person person : personList) {
            if(person.getAge() >= 18){
                targetList.add(person);
            }
        }
        return targetList;
    }
}
代码语言:javascript复制
/**
 * 过滤出性别为男的同学
 */
public class GenderFilter implements Filter {

    @Override
    public List<Person> filterOperate(List<Person> personList) {
        List<Person> targetList = new ArrayList<>();
        for (Person person : personList) {
            if("男".equals(person.getGender())){
                targetList.add(person);
            }
        }
        return targetList;
    }
}

最后,编写一个测试类如下:

代码语言:javascript复制
public class FilterClient {

    public static void main(String[] args) {
        List<Person> personList = new ArrayList<>();
        personList.add(new Person("程咬金","男",36));
        personList.add(new Person("露娜","女",16));
        personList.add(new Person("伽啰","女",18));
        personList.add(new Person("苏烈","男",40));
        personList.add(new Person("武则天","女",24));
        personList.add(new Person("韩信","男",16));

        //过程出年龄已满18周岁的同学
        Filter ageFilter = new AgeFilter();
        personList = ageFilter.filterOperate(personList);
        System.out.println(personList);
        System.out.println("========分隔符=======");

        //过滤出性别为男的同学
        Filter genderFilter = new GenderFilter();
        personList = genderFilter.filterOperate(personList);
        System.out.println(personList);
    }
}

输出结果:

代码语言:javascript复制
[Person{name='程咬金', gender='男', age=36}, Person{name='伽啰', gender='女', age=18}, Person{name='苏烈', gender='男', age=40}, Person{name='武则天', gender='女', age=24}]
========分隔符=======
[Person{name='程咬金', gender='男', age=36}, Person{name='苏烈', gender='男', age=40}]

当然,还可以按照姓名过滤,只需要写一个过滤器实现类,然后在客户端加入过滤即可!

三、应用

过滤器模式的应用,当属我们最熟悉的 JavaWeb 工程中的Filter,如果我们想自定义一个过滤器,只需要实现Filter即可!例如创建一个允许跨域的Filter过滤器,如下:

代码语言:javascript复制
/**
 * Servlet Filter implementation class CrossOriginFilter
 */
public class CrossOriginFilter implements Filter {
 
 private boolean isCross = false;

    /**
     * Default constructor. 
     */
    public CrossOriginFilter() {
        // TODO Auto-generated constructor stub
    }

 /**
  * @see Filter#destroy()
  */
 public void destroy() {
  // TODO Auto-generated method stub
 }

 /**
  * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
  */
 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  // TODO Auto-generated method stub
  // place your code here
  if(isCross){
   HttpServletRequest httpServletRequest = (HttpServletRequest)request;
            HttpServletResponse httpServletResponse = (HttpServletResponse)response;
            System.out.println("拦截请求: " httpServletRequest.getServletPath());
//            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");  
            httpServletResponse.setHeader("Access-Control-Allow-Origin", httpServletRequest.getHeader("Origin"));  
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");  
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
            httpServletResponse.setHeader("Access-Control-Max-Age", "3600");  
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with");  
  }
  // pass the request along the filter chain
  chain.doFilter(request, response);
 }

 /**
  * @see Filter#init(FilterConfig)
  */
 public void init(FilterConfig fConfig) throws ServletException {
  // TODO Auto-generated method stub
 }

}

四、总结

过滤器模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来,操作也比较简单,在实际开发中,使用非常广泛。

五、参考

1、菜鸟教程 - 过滤器模式

0 人点赞