概述
过滤器模式(Filter Pattern),又叫标准模式(Criteria Pattern),是一种结构型模式。
这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来,它可结合多个标准来获得单一标准。
优点:简单,解耦,使用方便。
使用场景:需要进行筛选时。
实例
下面将创建Student对象,Filter接口和该接口的实现类,基于各种标准和它们的组合来过滤Student对象的列表(如统计有多少男生,一年级的学生等)。
创建Student类
该类属性有姓名、性别和年级。
public class Student {
private String name;
private String gender;
private String grade;
//省略setter和getter方法,无参构造和带参构造
}
创建过滤器接口
public interface Filter {
//定义过滤方法
public List<Student> doFilt(List<Student> students);
}
创建Filter接口的实现类
男生过滤器
public class MaleFilter implements Filter {
public List<Student> doFilt(List<Student> students) {
List<Student> students2 = new ArrayList<Student>();
for(Student student : students) {
if(student.getGender().equalsIgnoreCase("男")) {
students2.add(student);
}
}
return students2;
}
}
女生过滤器
public class FemaleFilter implements Filter {
public List<Student> doFilt(List<Student> students) {
List<Student> students2 = new ArrayList<Student>();
for(Student student : students) {
if(student.getGender().equalsIgnoreCase("女")) {
students2.add(student);
}
}
return students2;
}
}
一年级学生过滤器
public class FirstGradeFilter implements Filter {
public List<Student> doFilt(List<Student> students) {
List<Student> students2 = new ArrayList<Student>();
for(Student student : students) {
if(student.getGrade().equalsIgnoreCase("一年级")) {
students2.add(student);
}
}
return students2;
}
}
二年级学生过滤器
public class SecondGradeFilter implements Filter {
public List<Student> doFilt(List<Student> students) {
List<Student> students2 = new ArrayList<Student>();
for(Student student : students) {
if(student.getGrade().equalsIgnoreCase("二年级")) {
students2.add(student);
}
}
return students2;
}
}
与过滤器(交集)
public class AndFilter implements Filter {
private Filter filter1;
private Filter filter2;
public AndFilter(Filter filter1,Filter filter2) {
this.filter1 = filter1;
this.filter2 = filter2;
}
public List<Student> doFilt(List<Student> students) {
List<Student> students2 = filter1.doFilt(students);
return filter2.doFilt(students2);
}
}
或过滤器(并集)
public class OrFilter implements Filter {
private Filter filter1;
private Filter filter2;
public OrFilter(Filter filter1,Filter filter2) {
this.filter1 = filter1;
this.filter2 = filter2;
}
public List<Student> doFilt(List<Student> students) {
List<Student> students1 = filter1.doFilt(students);
List<Student> students2 = filter2.doFilt(students);
for(Student student : students2) {
if(!students1.contains(student)) {
students1.add(student);
}
}
return students1;
}
}
测试类
public class FilterPatternDemo {
public static void main(String[] args) {
//定义对象列表
List<Student> students = new ArrayList<Student>();
students.add(new Student("叶凡","男","一年级"));
students.add(new Student("无始","男","一年级"));
students.add(new Student("狠人","女","一年级"));
students.add(new Student("荒","男","二年级"));
students.add(new Student("云曦","女","二年级"));
students.add(new Student("火灵儿","女","二年级"));
//定义过滤器对象
//男生过滤器
Filter maleFilter = new MaleFilter();
//女生过滤器
Filter femaleFilter = new FemaleFilter();
//一年级学生过滤器
Filter firstGradeFilter = new FirstGradeFilter();
//二年级学生过滤器
Filter secondGradeFilter = new SecondGradeFilter();
//一年级男生过滤器
Filter maleAndFirstGradeFilter = new MaleAndFirstGradeFilter(maleFilter,firstGradeFilter);
//女生或二年级学生过滤器
Filter femaleOrSecondGradeFilter = new FemaleOrSecondGradeFilter(femaleFilter,secondGradeFilter);
//使用不同的过滤器对对象列表进行过滤,根据需求进行统计
//统计所有男生
System.out.println("男生");
List<Student> students1 = maleFilter(students);
printStudent(students1);
System.out.println("==========================");
//统计所有二年级的学生
System.out.println("二年级学生");
List<Student> students2 = secondGradeFilter(students);
printStudent(students2);
System.out.println("==========================");
//统计一年级的男生(交集)
System.out.println("一年级男生");
List<Student> students3 = maleAndFirstGradeFilter(students);
printStudent(students3);
System.out.println("==========================");
//统计女生和二年级的学生(并集)
System.out.println("女生和二年级学生");
List<Student> students4 = femaleOrSecondGradeFilter(students);
printStudent(students4);
System.out.println("==========================");
}
//打印学生信息方法
public static void printStudent(List<Student> students) {
for(Student student : students) {
System.out.println("姓名:" + student.getName() + ",性别:" + student.getGender() + ",年级:" + student.getGrade());
}
}
}
打印结果为
通过上面的实例,可以发现,过滤器模式其实很简单,制定过滤规则,然后根据指定的标准进行过滤,得到符合条件的数据。但在构建过滤规则时较为繁琐,不过在java8之后,可使用stream流的方式更加方便地进行规则制定。