过滤器模式


过滤器模式

过滤器模式(Filter Pattern)是一种设计模式,它允许我们使用不同的标准来过滤一组对象,从而提取出我们需要的子集。该模式是建议的 Java 过滤器 API 的基础。

适用场景

  • 当您需要按特定标准从一组对象中提取子集时。
  • 当您需要以不同的方式多次过滤一组对象时。

优点

  • 可以轻松地使用不同的标准来过滤一组对象。
  • 可以提高代码的灵活性和可维护性。
  • 可以提高代码的可重用性。

组成部分

  • Filter:定义了过滤器的接口,包含对过滤器的操作的说明。
  • Criteria:定义了一个标准,以便我们可以根据不同标准从集合中过滤对象。
  • CriteriaImpl:实现了 Criteria 接口,以便我们可以根据不同的标准过滤集合对象。
  • AndCriteria:实现了 Criteria 接口,它返回满足两个标准的对象。
  • OrCriteria:实现了 Criteria 接口,它返回满足任意一个标准的对象。

实现步骤

  1. 创建一个过滤器接口 Filter,定义对过滤器的操作。
  2. 创建一个标准接口 Criteria,用于定义集合的标准。
  3. 创建一个实现 Criteria 接口的具体标准类 CriteriaImpl。
  4. 创建一个实现 Criteria 接口的 AndCriteria 类,用于返回满足两个标准的对象。
  5. 创建一个实现 Criteria 接口的 OrCriteria 类,用于返回满足任意一个标准的对象。
  6. 最后,创建一个过滤器管理类 FilterManager,它使用基本的过滤器来过滤对象。

示例代码:

public interface Filter {
   public List<Person> filter(List<Person> persons);
}

public class CriteriaMale implements Criteria {

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> malePersons = new ArrayList<Person>(); 
      
      for (Person person : persons) {
         if(person.getGender().equalsIgnoreCase("MALE")){
            malePersons.add(person);
         }
      }
      return malePersons;
   }
}

public class CriteriaFemale implements Criteria {

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> femalePersons = new ArrayList<Person>(); 
      
      for (Person person : persons) {
         if(person.getGender().equalsIgnoreCase("FEMALE")){
            femalePersons.add(person);
         }
      }
      return femalePersons;
   }
}

public class CriteriaSingle implements Criteria {

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> singlePersons = new ArrayList<Person>(); 
      
      for (Person person : persons) {
         if(person.getMaritalStatus().equalsIgnoreCase("SINGLE")){
            singlePersons.add(person);
         }
      }
      return singlePersons;
   }
}

public class AndCriteria implements Criteria {
   private Criteria criteria;
   private Criteria otherCriteria;

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

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> firstCriteriaPersons = criteria.meetCriteria(persons);        
      return otherCriteria.meetCriteria(firstCriteriaPersons);
   }
}

public class OrCriteria implements Criteria {
   private Criteria criteria;
   private Criteria otherCriteria;

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

   @Override
   public List<Person> meetCriteria(List<Person> persons) {
      List<Person> firstCriteriaItems = criteria.meetCriteria(persons);
      List<Person> otherCriteriaItems = otherCriteria.meetCriteria(persons);

      for (Person person : otherCriteriaItems) {
         if(!firstCriteriaItems.contains(person)){
            firstCriteriaItems.add(person);
         }
      }  
      return firstCriteriaItems;
   }
}

public class CriteriaPatternDemo {
   public static void main(String[] args) {
      List<Person> persons = new ArrayList<Person>();

      persons.add(new Person("Robert","Male", "Single"));
      persons.add(new Person("John", "Male", "Married"));
      persons.add(new Person("Laura", "Female", "Married"));
      persons.add(new Person("Diana", "Female", "Single"));
      persons.add(new Person("Mike", "Male", "Single"));
      persons.add(new Person("Bobby", "Male", "Single"));

      Criteria male = new CriteriaMale();
      Criteria female = new CriteriaFemale();
      Criteria single = new CriteriaSingle();
      Criteria singleMale = new AndCriteria(single, male);
      Criteria singleOrFemale = new OrCriteria(single, female);

      System.out.println("Males: ");
      printPersons(male.meetCriteria(persons));

      System.out.println("\nFemales: ");
      printPersons(female.meetCriteria(persons));

      System.out.println("\nSingle Males: ");
      printPersons(singleMale.meetCriteria(persons));

      System.out.println("\nSingle Or Females: ");
      printPersons(singleOrFemale.meetCriteria(persons));
   }

   public static void printPersons(List<Person> persons){
   
      for (Person person : persons) {
         System.out.println("Person : [ Name : " + person.getName() 
            +", Gender : " + person.getGender() 
            +", Marital Status : " + person.getMaritalStatus()
            +" ]");
      }
   }
}

结论

过滤器模式可以极大地提高代码的可重用性和可维护性,可以轻松地使用不同的标准来过滤一组对象。此外,它还可以方便地进行多次过滤,并可以增加过滤器链,这使得过滤器更加强大和灵活。