Filter Pattern,即过滤模式,通过不同的过滤标准,或者低耦合将过滤标准组合在一起,对一组对象进行过滤,属于结构类的设计模式。
下面是一个过滤模式的简单案例。
Criteria 定义过滤接口,CriteriaFemale, CriteriaMale, AndCriteria, OrCriteria 类实现过滤接口。Person 是被过滤的对象。CriteriaPatternDemo 演示过滤模式。
具体代码:
过滤对象 Person 的实现
public class Person { private String name; private String gender; private String maritalStatus; public Person(String name, String gender, String maritalStatus){ this.name = name; this.gender = gender; this.maritalStatus = maritalStatus; } public String getName() { return name; } public String getGender() { return gender; } public String getMaritalStatus() { return maritalStatus; } public String toString(){ return "name : " + this.name + ", gender : " + this.gender + ", maritalStatus : " + this.maritalStatus; } }
过滤接口定义
import java.util.List; public interface Criteria { public List<Person> meetCriteria(List<Person> persons); }
CriteriaFemal, CriteriaMale, CriteriaSingle 具体类实现 Criteria 接口,实现过滤具体逻辑
import java.util.LinkedList; import java.util.List; public class CriteriaFemale implements Criteria { @Override public List<Person> meetCriteria(List<Person> persons) { List<Person> meetPersons = new LinkedList<>(); for (Person p : persons){ if ("female".equals(p.getGender())){ meetPersons.add(p); } } return meetPersons; } }
import java.util.LinkedList; import java.util.List; public class CriteriaMale implements Criteria { @Override public List<Person> meetCriteria(List<Person> persons) { List<Person> meetPersons = new LinkedList<>(); for (Person p : persons){ if ("male".equals(p.getGender())){ meetPersons.add(p); } } return meetPersons; } }
import java.util.LinkedList; import java.util.List; public class CriteriaSingle implements Criteria { @Override public List<Person> meetCriteria(List<Person> persons) { List<Person> meetPersons = new LinkedList<>(); for (Person p : persons){ if ("single".equals(p.getMaritalStatus())){ meetPersons.add(p); } } return meetPersons; } }
AndCriteria, OrCriteria 基于基本过滤具体,进行逻辑运算
import java.util.List; 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> meetPersons = criteria.meetCriteria(persons); meetPersons = otherCriteria.meetCriteria(meetPersons); return meetPersons; } }
import java.util.List; 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> meetPersons1 = criteria.meetCriteria(persons); List<Person> meetPersons2 = otherCriteria.meetCriteria(persons); for (Person p : meetPersons2){ if (!meetPersons1.contains(p)){ meetPersons1.add(p); } } return meetPersons1; } }
演示代码,对一系列对象,进行单条件过滤,或者组合条件过滤
import java.util.LinkedList; import java.util.List; public class CriteriaPatternDemo { public static void main(){ List<Person> persons = new LinkedList<>(); persons.add(new Person("Mike", "male", "single")); persons.add(new Person("Lucy", "female", "married")); persons.add(new Person("Vivi", "female", "single")); persons.add(new Person("Eric", "male", "married")); persons.add(new Person("Lisa", "female", "single")); System.out.println("male :"); Criteria criteriaMale = new CriteriaMale(); CriteriaPatternDemo.printListPerson(criteriaMale.meetCriteria(persons)); System.out.println("female :"); Criteria criteriaFemale = new CriteriaFemale(); CriteriaPatternDemo.printListPerson(criteriaFemale.meetCriteria(persons)); System.out.println("sinlge female :"); Criteria criterSingle = new CriteriaSingle(); Criteria singleFemale = new AndCriteria(criterSingle, criteriaFemale); CriteriaPatternDemo.printListPerson(singleFemale.meetCriteria(persons)); System.out.println("sinlge or female :"); Criteria singleOrFemale = new OrCriteria(criteriaFemale, criterSingle); CriteriaPatternDemo.printListPerson(singleOrFemale.meetCriteria(persons)); } public static void printListPerson(List<Person> persons){ for (Person p : persons){ System.out.println("[" + p + "]"); } System.out.println(""); } }
拓展性考虑
例如,要增加一个过滤标准 married
1. 增加一个文件定义 CriteriaMarried 类,使其实现 Criteria 接口,实现过滤逻辑 meetCriteria()
2. 在客户端 CriteriaPatternDemo 使用新增的类 CriteriaMarried
既可使用新扩展的过滤标准。
参考资料
Design Patterns - Filter Pattern, TutorialsPoint