1 过滤器模式简介
@1 过滤器模式
属于结构型模式,种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来,它结合多个标准来获得单一标准。
@2 4W1H 模型解读过滤器模式
- why 过滤器模式的意图:以不同的标准过滤一组对象,通过逻辑运算解耦组合。
- what 主要解决:信息过滤和筛选问题。
- when/where 何时使用:
- 敏感词过滤、舆情监测。
- 需要对对象列表(或数据列表)进行校验、审查或预处理的场景。
- 对网络接口的请求和响应进行拦截,例如对每一个请求和响应记录日志,一遍日后分析。
- how 如何解决:通过逻辑运算以解耦的方式把它们连接起来,它结合多个标准来获得单一标准。
@3 过滤器模式优缺点
优点:
- 将对象的过滤、校验逻辑抽离出来,降低系统的复杂度。
- 过滤规则可实现重复利用。
缺点:性能较低,每个过滤器对每一个元素都会进行遍历。如果有n个元素,m个过滤器,则负责度为O(mn)。
@4 过滤器模式UML图
2 过滤器模式简单实现(Java)
2.1 创建基准类
创建一个类,在该类上应用标准。代码实现如下:
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;
}
}
2.2 创建标准类接口和实现接口的实体类
为标准创建一个接口。代码实现如下:
import java.util.List;
public interface Criteria {
public List<Person> meetCriteria(List<Person> persons);
}
创建实现了 Criteria 接口的实体类。代码实现如下:
import java.util.ArrayList;
import java.util.List;
//1 实体类 CriteriaMale,筛选男性
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;
}
}
//2 实体类 CriteriaFemale,筛选女性
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;
}
}
//3 实体类 CriteriaSingle,筛选单身
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;
}
}
//4 实体类 AndCriteria,与操作,同时满足两个标准
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);
}
}
//5 实体类 OrCriteria,或操作,两个标准满足任意一个即可
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;
}
}
2.3 demo测试类
代码实现如下:
import java.util.ArrayList;
import java.util.List;
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()
+"]");
}
}
}