过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
我们将创建一个 Person 对象、Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表。我们的演示类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Person 对象的列表。
简单的对象的创建
这里写了一些简单的额POJO对象,用于演示使用,主要就是Person和枚举类型.
- @Data 是Lombok提供的插件支持,没有的话,可以手写setter/getter方法
Person
import lombok.Data;import lombok.ToString;import lombok.experimental.Accessors;@Data@Accessors(chain = true)@ToStringpublic class Person {private String name;private String gender;private int age;public Person(String name, String gender, int age) {this.name = name;this.gender = gender;this.age = age;}}
GenderStatus
性别状态信息
/*** 作用:** <p>时间:2018/6/26 22:08** <p>位置:com.tao.example.design.criteria.entity** @author Yan - tao - zhoutao825638@vip.qq.com*/public enum GenderStatus {FEMALE,MALE}
过滤器的实现
过滤器接口
public interface Criteria {/*** 过滤器** @param persons* @return*/List<Person> meetCriteria(List<Person> persons);}
基本过滤器
男性过滤器
public class CriteriaMale implements Criteria {@Overridepublic List<Person> meetCriteria(List<Person> persons) {List<Person> collect =persons.stream().filter(person -> {return person.getGender().equals(GenderStatus.MALE.name());}).collect(Collectors.toList());return collect;}}
女性过滤器
public class CriteriaFemale implements Criteria {@Overridepublic List<Person> meetCriteria(List<Person> persons) {List<Person> collect =persons.stream().filter(person -> {return person.getGender().equals(GenderStatus.FEMALE.name());}).collect(Collectors.toList());return collect;}}
成年过滤器
public class CriteriaAdult implements Criteria {@Overridepublic List<Person> meetCriteria(List<Person> persons) {List<Person> personList =persons.stream().filter(person -> person.getAge() >= 18).collect(Collectors.toList());return personList;}}
逻辑过滤器组合
交集过滤器
提供两个基本过滤器,采用与操作线性过滤
public class AndCriteria implements Criteria {private Criteria mainCriteria;private Criteria otherCriteria;public AndCriteria(Criteria mainCriteria, Criteria otherCriteria) {this.mainCriteria = mainCriteria;this.otherCriteria = otherCriteria;}@Overridepublic List<Person> meetCriteria(List<Person> persons) {List<Person> mainCriteriaPersons = mainCriteria.meetCriteria(persons);List<Person> personList = otherCriteria.meetCriteria(mainCriteriaPersons);return personList;}}
并集过滤器
原理和交集过滤器类似
public class OrCriteria implements Criteria {private Criteria mainCriteria;private Criteria otherCriteria;public OrCriteria(Criteria mainCriteria, Criteria otherCriteria) {this.mainCriteria = mainCriteria;this.otherCriteria = otherCriteria;}@Overridepublic List<Person> meetCriteria(List<Person> persons) {List<Person> mainCriteriaPersons = mainCriteria.meetCriteria(persons);List<Person> otherCriteriaPersons = otherCriteria.meetCriteria(persons);mainCriteriaPersons.forEach(person -> {if (!otherCriteriaPersons.contains(mainCriteriaPersons)) {otherCriteriaPersons.add(person);}});return otherCriteriaPersons;}}
过滤效果测试
测试代码
使用如下代码测试
public class TestCriteriaPattern {public static void main(String[] args) {List<Person> persons = new ArrayList<Person>();persons.add(new Person("赵清雅", GenderStatus.FEMALE.name(), 15));persons.add(new Person("李建岺", GenderStatus.MALE.name(), 16));persons.add(new Person("冯蕙茞", GenderStatus.FEMALE.name(), 17));persons.add(new Person("周踵武", GenderStatus.MALE.name(), 18));persons.add(new Person("杨畹兮", GenderStatus.FEMALE.name(), 15));persons.add(new Person("姜驰骛", GenderStatus.MALE.name(), 21));// 创建过滤器CriteriaFemale criteriaFemale = new CriteriaFemale();CriteriaMale criteriaMale = new CriteriaMale();CriteriaAdult criteriaAdult = new CriteriaAdult();AndCriteria maleAndAdult = new AndCriteria(criteriaMale, criteriaAdult);AndCriteria femaleAndAdult = new AndCriteria(criteriaFemale, criteriaAdult);OrCriteria femaleOrAdult = new OrCriteria(criteriaFemale, criteriaAdult);printPersons("男性过滤器", criteriaMale.meetCriteria(persons));printPersons("女性过滤器", criteriaFemale.meetCriteria(persons));printPersons("成年过滤器", criteriaAdult.meetCriteria(persons));printPersons("成年男性过滤器", maleAndAdult.meetCriteria(persons));printPersons("成年女过滤器", femaleAndAdult.meetCriteria(persons));printPersons("女性或成年过滤器", femaleOrAdult.meetCriteria(persons));}public static void printPersons(String criteriaName, List<Person> personList) {System.out.println(criteriaName);if (personList.size() == 0){System.out.println("\t 没有找到");}personList.forEach(person -> {System.out.println("\t" + person);});System.out.println("---------------------");}}
测试输出
男性过滤器Person(name=李建岺, gender=MALE, age=16)Person(name=周踵武, gender=MALE, age=18)Person(name=姜驰骛, gender=MALE, age=21)---------------------女性过滤器Person(name=赵清雅, gender=FEMALE, age=15)Person(name=冯蕙茞, gender=FEMALE, age=17)Person(name=杨畹兮, gender=FEMALE, age=15)---------------------成年过滤器Person(name=周踵武, gender=MALE, age=18)Person(name=姜驰骛, gender=MALE, age=21)---------------------成年男性过滤器Person(name=周踵武, gender=MALE, age=18)Person(name=姜驰骛, gender=MALE, age=21)---------------------成年女过滤器没有找到---------------------女性或成年过滤器Person(name=周踵武, gender=MALE, age=18)Person(name=姜驰骛, gender=MALE, age=21)Person(name=赵清雅, gender=FEMALE, age=15)Person(name=冯蕙茞, gender=FEMALE, age=17)Person(name=杨畹兮, gender=FEMALE, age=15)---------------------
