1、过滤器模式的概念
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准。
2、实现
创建一个Person对象、Criteria接口和实现了该接口的实体类,来过滤Person对象的列表。CriteriaPatternDemo类使用Criteria对象,基于各种标准和它们的结合来过滤Person 对象的列表。
如下图:
(1)创建类
创建一个Person类,在该类上使用过滤标准:
public class Person {
private String name;// 姓名
private String sex;// 性别
private String maritalStatus;// 是否结婚
// 构造方法
public Person() {
}
public Person(String name, String sex, String maritalStatus) {
this.name = name;
this.sex = sex;
this.maritalStatus = maritalStatus;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getMaritalStatus() {
return maritalStatus;
}
public void setMaritalStatus(String maritalStatus) {
this.maritalStatus = maritalStatus;
}
}
(2)创建接口
为标准(Criteria)创建一个接口:
/*
* 过滤的标准接口
*/
public interface Criteria {
List<Person> meetCriteria(List<Person> persons);
}
(3)创建接口的实现类
创建实现了 Criteria 接口的实体类。
CriteriaMale这个实现类过滤男性出来:
/*
* 这个类只过滤男性出来
*/
public class CriteriaMale implements Criteria {
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> list = new ArrayList<>();
if (persons == null && persons.size() <= 0) {
return null;
}
for (Person p : persons) {
if (p.getSex().equalsIgnoreCase("MALE")) {
list.add(p);
}
}
return list;
}
}
CriteriaFemale这个实现类过滤女性出来:
/*
* 这个类只过滤女性出来
*/
public class CriteriaFemale implements Criteria {
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> list = new ArrayList<>();
if (persons == null && persons.size() <= 0) {
return null;
}
for (Person p : persons) {
if (p.getSex().equalsIgnoreCase("FEMALE")) {
list.add(p);
}
}
return list;
}
}
CriteriaSingle这个实现类过滤单身出来:
/*
* 这个类只过滤单身出来
*/
public class CriteriaSingle implements Criteria {
@Override
public List<Person> meetCriteria(List<Person> persons) {
List<Person> list = new ArrayList<>();
if (persons == null && persons.size() <= 0) {
return null;
}
for (Person p : persons) {
if ((p.getMaritalStatus().equalsIgnoreCase("SINGLE")) {
list.add(p);
}
}
return list;
}
}
AndCriteria这个实现类过滤两次列表:
/*
* 这个类执行两次过滤
*/
public class AndCriteria implements Criteria {
// 定义两个过滤标准接口
private Criteria criteria;
private Criteria criteria2;
// 构造方法
public AndCriteria(Criteria criteria, Criteria criteria2) {
this.criteria = criteria;
this.criteria2 = criteria2;
}
@Override
public List<Person> meetCriteria(List<Person> persons) {
if (persons == null && persons.size() <= 0) {
return null;
}
// 执行一次过滤,获取数据列表
List<Person> firstPersons = criteria.meetCriteria(persons);
// 对第一次过滤后的列表进行第二次过滤,获取数据列表
List<Person> secondPersons = criteria2.meetCriteria(firstPersons);
return secondPersons;
}
}
OrCriteria这个实现类过滤1次列表:
/*
* 这个类执行1次过滤
*/
public class OrCriteria implements Criteria {
// 定义两个过滤标准接口
private Criteria criteria;
private Criteria criteria2;
// 构造方法
public OrCriteria(Criteria criteria, Criteria criteria2) {
this.criteria = criteria;
this.criteria2 = criteria2;
}
@Override
public List<Person> meetCriteria(List<Person> persons) {
if (persons == null && persons.size() <= 0) {
return null;
}
// 使用过滤器1执行一次过滤,获取数据列表
List<Person> firstPersons = criteria.meetCriteria(persons);
// 使用过滤器2执行一次过滤,获取数据列表
List<Person> firstPersons2 = criteria2.meetCriteria(persons);
//遍历过滤器2过滤后的数据列表
for(Person p:firstPersons2) {
//如果过滤器1列表中不包含这个对象
if(!firstPersons.contains(p)) {
//将这个对象加到过滤器1过滤后的数据列表中
firstPersons.add(p);
}
}
return firstPersons;
}
}
(4)测试
public class TestFilter {
public static void main(String[] args) {
//数据列表
List<Person> persons = new ArrayList<>();
//准备5个数据对象
Person p0 = new Person("李狗蛋", "MALE", "SINGLE");
Person p2 = new Person("猿A", "MALE", "MARRIED");
Person p3 = new Person("媛B", "FEMALE", "MARRIED");
Person p4 = new Person("猿C", "MALE", "MARRIED");
Person p5 = new Person("媛D", "FEMALE", "SINGLE");
persons.add(p0);
persons.add(p2);
persons.add(p3);
persons.add(p4);
persons.add(p5);
//过滤男性
Criteria male = new CriteriaMale();
//过滤女性
Criteria female = new CriteriaFemale();
//过滤单身
Criteria single = new CriteriaSingle();
//过滤单身并且是男性
Criteria maleAndSingle = new AndCriteria(male, single);
//过滤单身或者女性
Criteria femaleOrSingle = new OrCriteria(female, single);
System.out.println("男性如下:");
printPersons(male.meetCriteria(persons));
System.out.println("-------------------------------------");
System.out.println("女性如下:");
printPersons(female.meetCriteria(persons));
System.out.println("-------------------------------------");
System.out.println("单身男性如下:");
printPersons(maleAndSingle.meetCriteria(persons));
System.out.println("-------------------------------------");
System.out.println("单身的或女性如下:");
printPersons(femaleOrSingle.meetCriteria(persons));
}
//定义一个方法,打印集合中各对象的属性
public static void printPersons(List<Person> persons) {
for(Person p:persons) {
System.out.println("姓名:" + p.getName() + "========>"
+ "性别:" + p.getSex() + "========>"
+ "是否单身:" + p.getMaritalStatus());
}
}
}
执行,控制台如下:
结果是正确的。
3、总结
过滤器模式使用多种标准来过滤同一组数据列表,这样做的好处是每种标准之间是解耦的,但是可以把它们联和起来,用来对同一组数据进行过滤,来获取过滤后的数据列表。