zoukankan      html  css  js  c++  java
  • 设计模式系列之过滤器模式(Chriteria Pattern)

    过滤器模式(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)
    @ToString
    public 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 {
      @Override
      public 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 {
      @Override
      public 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 {
    
      @Override
      public 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;
      }
    
      @Override
      public 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;
      }
    
      @Override
      public 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("	 没有找到");
            }
        personList.forEach(
            person -> {
              System.out.println("	" + 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)
    ---------------------
    
  • 相关阅读:
    十天冲刺---Day10
    十天冲刺---Day9
    团队博客目录
    【Beta阶段】M2事后分析
    【Beta阶段】展示博客
    【Beta阶段】测试报告
    【Beta阶段】发布说明
    【Beta阶段】团队源代码管理
    【Beta阶段】第十次Scrum Meeting!!!
    【Beta阶段】第九次Scrum Meeting!(论坛已成功上线)
  • 原文地址:https://www.cnblogs.com/zhoutao825638/p/10382167.html
Copyright © 2011-2022 走看看