一、过滤器模式
过滤器模式(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 {@Overridepublic 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 {@Overridepublic 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 {@Overridepublic 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);}}
运行结果:
至此,整个过滤器模式就基本实现了,注意体会代码之间的关系,我们下回再见。