特点
过滤器模式也叫标准模式,允许开发人员根据标准过滤一组对象,通过逻辑运算解耦应用程序。
程序代码
pojo 对象Person类
@Slf4j
@Data
@Accessors(chain = true)
public class Person {
private int age;
private boolean married;
private int sex;
}
标准接口类
public interface Criterion {
List<Person> filter(List<Person> persons);
}
按照年龄查询
public class AgeCriterion implements Criterion{
private int[] age;
public AgeCriterion(int[] age) {
this.age = age;
}
@Override
public List<Person> filter(List<Person> persons) {
return persons.stream().filter(person -> person.getAge() >= age[0])
.filter(person -> person.getAge() <= age[1])
.collect(Collectors.toList());
}
}
按照婚姻状况查询
@Slf4j
public class MarriedCriterion implements Criterion{
private boolean married;
public MarriedCriterion(boolean married) {
this.married = married;
}
@Override
public List<Person> filter(List<Person> persons) {
return persons.stream().filter(person -> person.isMarried() == married)
.collect(Collectors.toList());
}
}
按照性别查询
public class SexCriterion implements Criterion{
private int sex;
public SexCriterion(int sex){
this.sex = sex;
}
@Override
public List<Person> filter(List<Person> persons) {
return persons.stream()
.filter(person -> person.getSex() == sex)
.collect(Collectors.toList());
}
}
组合查询
public class AndCriterion implements Criterion{
private List<Criterion> criterions = new ArrayList<>();
public AndCriterion(Criterion criterion) {
this.criterions.add(criterion);
}
@Override
public List<Person> filter(List<Person> persons) {
List<Person> resList = persons;
for (int i = 0; i < criterions.size(); i++) {
Criterion criterion = criterions.get(i);
resList = criterion.filter(resList);
}
return resList;
}
public AndCriterion add(Criterion criterion){
this.criterions.add(criterion);
return this;
}
}
测试代码
组装数据
private List<Person> list (){
return Arrays.asList(
new Person().setAge(18).setMarried(false).setSex(0),
new Person().setAge(19).setMarried(false).setSex(0),
new Person().setAge(20).setMarried(true).setSex(0),
new Person().setAge(21).setMarried(true).setSex(1),
new Person().setAge(25).setMarried(true).setSex(1)
);
}
测试
@Test
public void testCriterion(){
List<Person> list = list();
// 获取18-20的人
Criterion ageCriterion = new AgeCriterion(new int[]{18, 20});
List<Person> list1 = ageCriterion.filter(list);
log.info("18-20过滤结果: {}",list1);
// 获取已结婚的
Criterion marriedCriterion = new MarriedCriterion(true);
List<Person> list2 = marriedCriterion.filter(list);
log.info("已结婚过滤结果: {}",list2);
// 获取性别为男
Criterion sexCriterion = new SexCriterion(0);
List<Person> list3 = sexCriterion.filter(list);
log.info("性别为男过滤结果: {}",list3);
// 获取年龄 18-20 并且已婚 并且性别为男
AndCriterion andCriterion = new AndCriterion(ageCriterion)
.add(marriedCriterion)
.add(sexCriterion);
List<Person> list4 = andCriterion.filter(list);
log.info("年龄 18-20 并且已婚 并且性别为男过滤结果: {}",list4);
}
日志信息
17:16:42.756 [main] INFO org.example.singleton.CriterionTest - 18-20过滤结果: [Person(age=18, married=false, sex=0), Person(age=19, married=false, sex=0), Person(age=20, married=true, sex=0)]
17:16:42.765 [main] INFO org.example.singleton.CriterionTest - 已结婚过滤结果: [Person(age=20, married=true, sex=0), Person(age=21, married=true, sex=1), Person(age=25, married=true, sex=1)]
17:16:42.766 [main] INFO org.example.singleton.CriterionTest - 性别为男过滤结果: [Person(age=18, married=false, sex=0), Person(age=19, married=false, sex=0), Person(age=20, married=true, sex=0)]
17:16:42.767 [main] INFO org.example.singleton.CriterionTest - 年龄 18-20 并且已婚 并且性别为男过滤结果: [Person(age=20, married=true, sex=0)]
从代码来看,实现了代码解耦,当需要添加条件时,无需更改比较代码逻辑。满足开闭原则。