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

实现

我们将创建一个 Person 对象、Criteria 接口和实现了该接口的实体类,来过滤 Person 对象的列表。CriteriaPatternDemo 类使用 Criteria 对象,基于各种标准和它们的结合来过滤 Person 对象的列表。
8. 过滤器模式 - 图1

步骤 1

创建一个类,在该类上应用标准。

  1. package org.example.FilterPattern;
  2. /**
  3. * 人
  4. */
  5. public class Person {
  6. private String name;
  7. private String gender;
  8. private String maritalStatus;
  9. public Person(String name,String gender,String maritalStatus){
  10. this.name = name;
  11. this.gender = gender;
  12. this.maritalStatus = maritalStatus;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public String getGender() {
  18. return gender;
  19. }
  20. public String getMaritalStatus() {
  21. return maritalStatus;
  22. }
  23. }

步骤 2

为标准(Criteria)创建一个接口。

  1. package org.example.FilterPattern;
  2. import java.util.List;
  3. /**
  4. * 标准
  5. */
  6. public interface Criteria {
  7. public List<Person> meetCriteria(List<Person> persons);
  8. }

步骤 3

创建实现了 Criteria 接口的实体类。

  1. package org.example.FilterPattern;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 标准的女
  6. */
  7. public class CriteriaFemale implements Criteria {
  8. @Override
  9. public List<Person> meetCriteria(List<Person> persons) {
  10. List<Person> femalePersons = new ArrayList<Person>();
  11. for (Person person : persons) {
  12. if(person.getGender().equalsIgnoreCase("FEMALE")){
  13. femalePersons.add(person);
  14. }
  15. }
  16. return femalePersons;
  17. }
  18. }
  1. package org.example.FilterPattern;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 标准的男性
  6. */
  7. public class CriteriaMale implements Criteria {
  8. @Override
  9. public List<Person> meetCriteria(List<Person> persons) {
  10. List<Person> malePersons = new ArrayList<Person>();
  11. for (Person person : persons) {
  12. if(person.getGender().equalsIgnoreCase("MALE")){
  13. malePersons.add(person);
  14. }
  15. }
  16. return malePersons;
  17. }
  18. }
  1. package org.example.FilterPattern;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 标准单
  6. */
  7. public class CriteriaSingle implements Criteria {
  8. @Override
  9. public List<Person> meetCriteria(List<Person> persons) {
  10. List<Person> singlePersons = new ArrayList<Person>();
  11. for (Person person : persons) {
  12. if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){
  13. singlePersons.add(person);
  14. }
  15. }
  16. return singlePersons;
  17. }
  18. }
  1. package org.example.FilterPattern;
  2. import java.util.List;
  3. /**
  4. * 或者标准
  5. */
  6. public class OrCriteria implements Criteria {
  7. private Criteria criteria;
  8. private Criteria otherCriteria;
  9. public OrCriteria(Criteria criteria, Criteria otherCriteria) {
  10. this.criteria = criteria;
  11. this.otherCriteria = otherCriteria;
  12. }
  13. @Override
  14. public List<Person> meetCriteria(List<Person> persons) {
  15. List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
  16. List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);
  17. for (Person person : otherCriteriaItems) {
  18. if(!firstCriteriaItems.contains(person)){
  19. firstCriteriaItems.add(person);
  20. }
  21. }
  22. return firstCriteriaItems;
  23. }
  24. }
  1. package org.example.FilterPattern;
  2. import java.util.List;
  3. /**
  4. * 和标准
  5. */
  6. public class AndCriteria implements Criteria {
  7. private Criteria criteria;
  8. private Criteria otherCriteria;
  9. public AndCriteria(Criteria criteria, Criteria otherCriteria) {
  10. this.criteria = criteria;
  11. this.otherCriteria = otherCriteria;
  12. }
  13. @Override
  14. public List<Person> meetCriteria(List<Person> persons) {
  15. List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);
  16. return otherCriteria.meetCriteria(firstCriteriaPersons);
  17. }
  18. }

步骤4

使用不同的标准(Criteria)和它们的结合来过滤 Person 对象的列表。

  1. package org.example.FilterPattern;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 标准模式演示
  6. */
  7. public class CriteriaPatternDemo {
  8. public static void main(String[] args) {
  9. List<Person> persons = new ArrayList<Person>();
  10. persons.add(new Person("Robert","Male", "Single"));
  11. persons.add(new Person("John","Male", "Married"));
  12. persons.add(new Person("Laura","Female", "Married"));
  13. persons.add(new Person("Diana","Female", "Single"));
  14. persons.add(new Person("Mike","Male", "Single"));
  15. persons.add(new Person("Bobby","Male", "Single"));
  16. Criteria male = new CriteriaMale();
  17. Criteria female = new CriteriaFemale();
  18. Criteria single = new CriteriaSingle();
  19. Criteria singleMale = new AndCriteria(single, male);
  20. Criteria singleOrFemale = new OrCriteria(single, female);
  21. System.out.println("Males: ");
  22. printPersons(male.meetCriteria(persons));
  23. System.out.println("\nFemales: ");
  24. printPersons(female.meetCriteria(persons));
  25. System.out.println("\nSingle Males: ");
  26. printPersons(singleMale.meetCriteria(persons));
  27. System.out.println("\nSingle Or Females: ");
  28. printPersons(singleOrFemale.meetCriteria(persons));
  29. }
  30. public static void printPersons(List<Person> persons){
  31. for (Person person : persons) {
  32. System.out.println("Person : [ Name : " + person.getName()
  33. +", Gender : " + person.getGender()
  34. +", Marital Status : " + person.getMaritalStatus()
  35. +" ]");
  36. }
  37. }
  38. }

image.png