Github: CriteriaPattern.java
    过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
    过滤器模式 - 图1

    1. 创建Person类

      1. public class Person {
      2. private String name;
      3. private String gender;
      4. private String maritalStatus;
      5. public Person(String name, String gender, String maritalStatus) {
      6. this.name = name;
      7. this.gender = gender;
      8. this.maritalStatus = maritalStatus;
      9. }
      10. public String getName() {
      11. return name;
      12. }
      13. public String getGender() {
      14. return gender;
      15. }
      16. public String getMaritalStatus() {
      17. return maritalStatus;
      18. }
      19. @Override
      20. public String toString() {
      21. return "Person{" + "name='" + name + '\'' + ", gender='" + gender + '\'' + ", maritalStatus='" + maritalStatus + '\'' + '}';
      22. }
      23. }
    2. 定义过滤器接口,统一的过滤方法

      1. /**
      2. * 过滤器接口
      3. */
      4. public interface Criteria{
      5. List<Person> meetCriteria(List<Person> personList);
      6. }
    3. 定义男女性别过滤实现类 ```java /**

      • 男性过滤器 */ public class CriteriaMale implements Criteria { @Override public List meetCriteria(List personList) { return personList.stream().filter(p -> “male”.equalsIgnoreCase(p.getGender())).collect(Collectors.toList()); } }

    /**

    • 女性过滤器 */ public class CriteriaFemale implements Criteria{ @Override public List meetCriteria(List personList) {
      1. return personList.stream().filter(p -> "female".equalsIgnoreCase(p.getGender())).collect(Collectors.toList());
      } } ```
    1. 定义Person婚姻状态实现类 ```java /**
      • 单身过滤器 */ public class CriteriaSingle implements Criteria{ @Override public List meetCriteria(List personList) { return personList.stream().filter(p -> “single”.equalsIgnoreCase(p.getMaritalStatus())).collect(Collectors.toList()); } }

    /**

    • 已婚过滤器 */ public class CriteriaMarried implements Criteria{ @Override public List meetCriteria(List personList) {
      1. return personList.stream().filter(p -> "married".equalsIgnoreCase(p.getMaritalStatus())).collect(Collectors.toList());
      } } ```
    1. 定义逻辑过滤器: 并且 实现类 ```java /**

      • and: 并且逻辑 */ public class AndCriteria implements Criteria{ private Criteria criteria; private Criteria otherCriteria;

        private AndCriteria() { }

        public AndCriteria(Criteria criteria, Criteria otherCriteria) { this.criteria = criteria; this.otherCriteria = otherCriteria; }

        @Override public List meetCriteria(List personList) { // 1. 筛选出部分person List criteriaPerson = criteria.meetCriteria(personList); // 2. 再从步骤1筛选的结果中再筛选,从而达到and效果 return otherCriteria.meetCriteria(criteriaPerson); } }

    /**

    • or: 或逻辑 */ public class OrCriteria implements Criteria{ private Criteria criteria; private Criteria otherCriteria;

      private OrCriteria() { }

      public OrCriteria(Criteria criteria, Criteria otherCriteria) {

      1. this.criteria = criteria;
      2. this.otherCriteria = otherCriteria;

      }

      @Override public List meetCriteria(List personList) {

      1. // 1. 筛选出各自的person
      2. List<Person> people = criteria.meetCriteria(personList);
      3. List<Person> people1 = otherCriteria.meetCriteria(personList);
      4. // 2. 此时,将2个结果合并返回即是or的结果。但是防止数据重复,则有个排重逻辑
      5. for (Person person : people1) {
      6. if(!people.contains(person)){
      7. people.add(person);
      8. }
      9. }
      10. return people;

      } } ```

    1. 测试 ```java public static void main(String[] args) { CriteriaPattern pattern = new CriteriaPattern(); pattern.criteria(); }

    private void criteria() { List list = new ArrayList<>(); list.add(new Person(“s”, “male”, “single”)); list.add(new Person(“s”, “female”, “single”)); list.add(new Person(“ss”, “female”, “single”)); list.add(new Person(“ssf”, “female”, “single”)); list.add(new Person(“ssfs”, “male”, “single”)); list.add(new Person(“asdf”, “male”, “married”));

    1. Criteria female = new CriteriaFemale();
    2. List<Person> femalePerson = female.meetCriteria(list);
    3. System.out.println("female:");
    4. System.out.println(femalePerson);
    5. Criteria male = new CriteriaMale();
    6. List<Person> malePeople = male.meetCriteria(list);
    7. System.out.println("\nmale:");
    8. System.out.println(malePeople);
    9. Criteria single = new CriteriaSingle();
    10. List<Person> singlePerson = single.meetCriteria(list);
    11. System.out.println("\nsingle:");
    12. System.out.println(singlePerson);
    13. Criteria or = new OrCriteria(female, single);
    14. List<Person> orPerson = or.meetCriteria(list);
    15. System.out.println("\nfemale or single:");
    16. System.out.println(orPerson);

    }

    1. 输出结果:
    2. ```java
    3. female:
    4. [Person{name='s', gender='female', maritalStatus='single'}, Person{name='ss', gender='female', maritalStatus='single'}, Person{name='ssf', gender='female', maritalStatus='single'}]
    5. male:
    6. [Person{name='s', gender='male', maritalStatus='single'}, Person{name='ssfs', gender='male', maritalStatus='single'}, Person{name='asdf', gender='male', maritalStatus='married'}]
    7. single:
    8. [Person{name='s', gender='male', maritalStatus='single'}, Person{name='s', gender='female', maritalStatus='single'}, Person{name='ss', gender='female', maritalStatus='single'}, Person{name='ssf', gender='female', maritalStatus='single'}, Person{name='ssfs', gender='male', maritalStatus='single'}]
    9. female or single:
    10. [Person{name='s', gender='female', maritalStatus='single'}, Person{name='ss', gender='female', maritalStatus='single'}, Person{name='ssf', gender='female', maritalStatus='single'}, Person{name='s', gender='male', maritalStatus='single'}, Person{name='ssfs', gender='male', maritalStatus='single'}]

    这里性别,婚姻状态直接是字符串,可以使用枚举替换,更好一些。

    如果想根据年龄来过滤童年,中年,老年等。可以在Person增加age变量,并且增加相应年龄段的过滤器(比如增加同年童年过滤器)。