过滤器模式

定义:

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

类图:

过滤器模式

 

 这张图是网络摘的,基本上就是按这张图写的:

接口:

public interface Criteria {
    List<Person> meetCriteria(List<Person> persons);
}

各种实现类,多列举了几个:

public class GirlCriteria implements Criteria{
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> girlPersons = new ArrayList<>();
        for (Person person : persons) {
            if(person.getGender().equals("GIRL")) {
                girlPersons.add(person);
            }
        }
        return girlPersons;
    }
}
public class BoyCriteria implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> boyPersons = new ArrayList<>();
        for (Person person : persons) {
            if(person.getGender().equals("BOY")) {
                boyPersons.add(person);
            }
        }
        return boyPersons;
    }
}
public class SingleCriteria implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> singlePersons = new ArrayList<>();
        for (Person person : persons) {
            if(person.getStatus().equals("SINGLE")) {
                singlePersons.add(person);
            }
        }
        return singlePersons;
    }
}
//同时满足这两个条件的
public class AndCriteria implements Criteria {
    private Criteria c1;
    private Criteria c2;
    public AndCriteria (Criteria c1, Criteria c2) {
        this.c1 = c1;
        this.c2 = c2;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> c1Person = c1.meetCriteria(persons);
        List<Person> andPerson = c2.meetCriteria(c1Person);
        return andPerson;
    }
}
// 满足条件之一的
public class OrCriteria implements Criteria {
    private Criteria c1;
    private Criteria c2;

    public OrCriteria(Criteria c1, Criteria c2) {
        this.c1 = c1;
        this.c2 = c2;
    }

    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> list1 = c1.meetCriteria(persons);
        List<Person> list2 = c2.meetCriteria(persons);
        for (Person person : list2) {
            if (!list1.contains(person)) {
                list1.add(person);
            }
        }
        return list1;
    }
}

测试类:

public class TestCriteria {
    public static void main(String[] args) {
        List<Person> persons = new ArrayList<Person>();
        persons.add(new Person("Robert", "BOY", "SINGLE"));
        persons.add(new Person("John", "BOY", "MARRIED"));
        persons.add(new Person("Laura", "GIRL", "MARRIED"));
        persons.add(new Person("Diana", "GIRL", "SINGLE"));
        persons.add(new Person("Mike", "BOY", "SINGLE"));
        persons.add(new Person("Bobby", "BOY", "SINGLE"));

        // 过滤只有BOY的
        System.out.println("boy:");
        List<Person> list1 = new BoyCriteria().meetCriteria(persons);
        printList(list1);

        // 过滤只有GIRL的
        System.out.println("girl:");
        List<Person> list2 = new GirlCriteria().meetCriteria(persons);
        printList(list2);

        // 过滤只有SINGLE的
        System.out.println("single:");
        List<Person> list3 = new SingleCriteria().meetCriteria(persons);
        printList(list3);

        // 过滤BOY并且SINGLE的
        System.out.println("boy and single:");
        BoyCriteria c1 = new BoyCriteria();
        SingleCriteria c2 = new SingleCriteria();
        List<Person> list4 = new AndCriteria(c1, c2).meetCriteria(persons);
        printList(list4);

        // 过滤GIRL或者SINGLE的
        GirlCriteria c3 = new GirlCriteria();
        SingleCriteria c4 = new SingleCriteria();
        System.out.println("girl or single:");
        List<Person> list5 = new OrCriteria(c3, c4).meetCriteria(persons);
        printList(list5);
    }

    public static void printList(List<Person> list) {
        for (Person person : list) {
            System.out.println(person);
        }
    }
}

测试结果:

过滤器模式

 

上一篇:SpringBoot 中 MongoDB 的简单使用


下一篇:mongoTemplate聚合统计字段类型为字符串的数据,根据时间日期月份进行统计,日期也为字符串