一、过滤器模式
过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式允许开发人员使用不同的标准来过滤一组对象,通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式,它结合多个标准来获得单一标准
二、组件介绍
1、过滤器接口(Filter)
定义了过滤器的基本方法,具体的实现还要具体过滤器角色去参与,在实际应用中可以扩展该接口以适应不同的过滤条件
2 具体命过滤器(ConcreteFilter)
实现了过滤器接口,负责执行具体的过滤操作。对数据进行过滤
3 过滤链(FilterChain)
将多个过滤器按照一定的顺序组合起来,形成一个过滤器链,依次对数据进行过滤
三、代码实战
1、Person
package com.xu.demo.filterPattern;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 数据实体类
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;//姓名
private String sex; // M表示男性,F表示女性
private Integer age;//年龄
}
2、IFilter
package com.xu.demo.filterPattern;
import java.util.List;
/**
* 过滤器接口
*/
public interface IFilter {
/**
* 过滤操作
* @param personList
* @return
*/
List<Person> filterOperate(List<Person> personList);
}
3、NameFilter
package com.xu.demo.filterPattern;
import java.util.List;
/**
* 过滤出性别为男的同学
*/
public class NameFilter implements IFilter {
@Override
public List<Person> filterOperate(List<Person> personList) {
return personList.stream().filter(person ->
person.getName().startsWith("J")).toList();
}
}
4、AgeFilter
package com.xu.demo.filterPattern;
import java.util.List;
/**
* 过滤已满足18岁的同学
*/
public class AgeFilter implements IFilter {
@Override
public List<Person> filterOperate(List<Person> personList) {
return personList.stream().filter(person ->
person.getAge() > 25).toList();
}
}
5、SexFilter
package com.xu.demo.filterPattern; import java.util.List; /** * 过滤已满足18岁的同学 */ public class SexFilter implements IFilter { @Override public List<Person> filterOperate(List<Person> personList) { return personList.stream().filter(person -> "M".equals(person.getSex())).toList(); } }
6、FilterChain
package com.xu.demo.filterPattern;
import org.apache.commons.collections.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
public class FilterChain {
private List<IFilter> filters;
public FilterChain(List<IFilter> filters) {
this.filters = filters;
}
public List<Person> doFilter(List<Person> personList) {
if (CollectionUtils.isEmpty(filters) || CollectionUtils.isEmpty(personList)) {
return new ArrayList<>();
}
List<Person> afterFilterShapes = new ArrayList<>(personList);
// 执行过滤
for (IFilter filter : filters) {
afterFilterShapes = filter.filterOperate(afterFilterShapes);
}
return afterFilterShapes;
}
}
7、FilterPattern
package com.xu.demo.filterPattern;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FilterPattern {
public static void main(String[] args) {
//待过滤的数据
List<Person> peoples = new ArrayList<>();
peoples.add(new Person("Jenny", "F", 20));
peoples.add(new Person("John", "M", 30));
peoples.add(new Person("Jack", "M", 35));
peoples.add(new Person("Mark", "M", 30));
peoples.add(new Person("Ronnie", "M", 25));
peoples.add(new Person("Ding", "M", 25));
peoples.add(new Person("Janet", "F", 35));
peoples.add(new Person("Jessie", "F", 25));
//过滤器
IFilter nameFilter = new NameFilter();
IFilter ageFilter = new AgeFilter();
IFilter sexFilter = new SexFilter();
//过滤链
FilterChain filter1 = new FilterChain(Arrays.asList(nameFilter, ageFilter));
FilterChain filter2 = new FilterChain(Arrays.asList(ageFilter, sexFilter));
FilterChain filter3 = new FilterChain(Arrays.asList(nameFilter, sexFilter));
//过滤链过滤出数据
List<Person> filteredPeople1 = filter1.doFilter(peoples);
List<Person> filteredPeople2 = filter2.doFilter(peoples);
List<Person> filteredPeople3 = filter3.doFilter(peoples);
System.out.println("================名字以J开头和年龄大于25岁==================");
filteredPeople1.forEach(System.out::println);
System.out.println("================年龄大于25岁和性别是M男性==================");
filteredPeople2.forEach(System.out::println);
System.out.println("================名字以J开头和性别是M男性===================");
filteredPeople3.forEach(System.out::println);
}
}
运行结果:
至此,整个过滤器模式就基本实现了,注意体会代码之间的关系,我们下回再见。