过滤器模式
1/27/24About 5 min
过滤器模式(Filter Pattern)允许开发人员通过逻辑条件对对象集合进行筛选操作,而不需要修改这些对象。这种模式属于行为型设计模式,通过提供一系列的过滤器来处理数据集,并根据需要选择合适的过滤器。

在过滤器模式中,主要包含以下角色:
- 目标接口(Target Interface): 这个接口定义了所有待过滤对象共享的方法,通常用于获取原始数据集。
- 具体目标类(Concrete Target): 实现目标接口的具体类,包含了要被过滤的数据集合。
- 过滤器接口(Filter Interface): 定义了一个抽象方法,该方法接受目标对象并可能返回一个经过过滤的新集合。每个过滤器都实现了这个接口。
- 具体过滤器类(Concrete Filter): 每个具体过滤器类实现过滤器接口,并定义了具体的过滤逻辑。它们可以链接起来形成过滤链,以便对数据进行多级过滤。
代码实现
有这么一个需求,我们希望将分数高于某个分数的学生筛选出来,这时候可以使用过滤器模式。
目标接口
目标接口暴露提供给过滤器使用的条件。
public interface Student {
double getScore();
String getName();
}具体目标类
具体目标类中我们维护学生的姓名及分数。
public class ConcreteStudent implements Student {
private String name;
private double score;
public ConcreteStudent(String name, double score) {
this.name = name;
this.score = score;
}
@Override
public double getScore() {
return score;
}
@Override
public String getName() {
return name;
}
}过滤器接口
过滤器接口接收所有学生的结合,通过子类实现过滤逻辑,返回满足条件的学生集合。
public interface Criteria {
List<Student> meetCriteria(List<Student> students);
}具体过滤器类
具体过滤器中需要指定分数线,并按照这个参数对输入的集合进行过滤。
public class HighScoreCriteria implements Criteria {
private double passingScore;
public HighScoreCriteria(double passingScore) {
this.passingScore = passingScore;
}
@Override
public List<Student> meetCriteria(List<Student> students) {
List<Student> filteredStudents = new ArrayList<>();
for (Student student : students) {
if (student.getScore() >= passingScore) {
filteredStudents.add(student);
}
}
return filteredStudents;
}
}使用
public class Client {
public static void main(String[] args) {
List<Student> students = Arrays.asList(
new ConcreteStudent("Alice", 90),
new ConcreteStudent("Bob", 85),
new ConcreteStudent("Charlie", 70)
);
Criteria highScoreFilter = new HighScoreCriteria(85);
List<Student> highScoringStudents = highScoreFilter.meetCriteria(students);
for (Student student : highScoringStudents) {
System.out.println(student.getName() + " 的分数为: " + student.getScore());
}
}
}结果:

过滤器模式与其他模式的对比
| 模式 | 功能 | 实现方式 | 适用场景 |
|---|---|---|---|
| 过滤器模式 | 数据筛选与过滤 | 定义过滤器接口,实现不同过滤逻辑 | 需要对数据进行多条件筛选时 |
| 迭代器模式 | 顺序访问集合元素 | 统一遍历接口,隐藏内部实现 | 需要统一遍历不同集合时 |
| 策略模式 | 封装可替换算法 | 定义算法族,客户端选择使用 | 需要根据条件选择不同算法时 |
| 责任链模式 | 避免请求发送者与接收者耦合 | 请求沿责任链传递,直到被处理 | 需要动态决定请求处理者时 |
总结
核心思想
过滤器模式的核心思想是通过定义一系列过滤器,对对象集合进行筛选和过滤,而不需要修改这些对象本身。这种模式将过滤逻辑与对象分离,使得可以灵活地组合和应用不同的过滤条件,实现复杂的数据筛选功能。
主要角色
- 目标接口(Target Interface):定义了所有待过滤对象共享的方法,用于获取过滤条件
- 具体目标类(Concrete Target):实现目标接口的具体类,包含要被过滤的数据集合
- 过滤器接口(Filter Interface):定义了过滤方法,接收对象集合并返回过滤后的集合
- 具体过滤器类(Concrete Filter):实现过滤器接口,包含具体的过滤逻辑
实现方式
- 定义目标接口,包含获取过滤条件的方法
- 实现具体目标类,存储待过滤的数据
- 定义过滤器接口,包含过滤方法
- 实现具体过滤器类,重写过滤方法,实现具体的过滤逻辑
- 客户端创建过滤器对象,调用过滤方法进行数据筛选
优缺点
优点:
- 符合单一职责原则,每个过滤器只负责一种过滤逻辑
- 提高了代码的复用性,过滤器可以在多个场景中使用
- 支持链式调用,可以组合多个过滤器实现复杂的过滤逻辑
- 符合开闭原则,添加新的过滤条件只需添加新的过滤器类
- 实现了过滤逻辑与数据对象的分离
缺点:
- 如果过滤器数量过多,可能会导致系统复杂度增加
- 过滤器链过长可能会影响性能
- 某些复杂的过滤条件可能需要多个过滤器组合实现
- 调试和测试过滤器链可能变得困难
适用场景
- 需要对数据集合进行多条件筛选和过滤
- 过滤条件需要灵活组合和复用
- 需要将过滤逻辑与数据对象分离
- 需要添加新的过滤条件而不修改现有代码
- 数据查询、日志过滤、权限验证、内容过滤等场景
实际应用
- 电商平台商品筛选:根据价格、品牌、销量等条件过滤商品
- 搜索引擎:根据关键词、时间、类型等条件过滤搜索结果
- 日志系统:根据日志级别、时间、模块等条件过滤日志
- 权限控制系统:根据用户角色、权限等级等条件过滤可访问资源
- 邮件过滤:根据发件人、主题、内容等条件过滤邮件
- 数据报表系统:根据时间范围、数据类型等条件过滤报表数据