2.3 过滤器模式
过滤器模式(Filter,也叫标准模式 Criteria)的想法很朴素:把每一条筛选规则都做成一个独立对象,再让这些对象自由组合,从一堆数据里挑出满足条件的子集。
它不是 GoF 的 23 个经典模式之一,但在业务系统里极其常见——任何“按多条件查询/筛选”的场景都能用到。它的精髓和函数式里的“谓词组合”是一回事。
下面的筛选器让你勾选若干条件对象,实时看到结果集如何收缩。
正在加载交互实验...
把条件做成对象
java
interface Criteria {
List<Person> meet(List<Person> people);
}
class CriteriaMale implements Criteria {
public List<Person> meet(List<Person> people) {
return people.stream().filter(Person::isMale).toList();
}
}每个 Criteria 都能被单独测试、单独复用。这正是它比一长串内联 if 更可维护的原因。
用 And / Or / Not 组合
真正强大的地方在于:组合子本身也是 Criteria。
java
class AndCriteria implements Criteria {
private Criteria a, b;
public List<Person> meet(List<Person> people) {
return b.meet(a.meet(people)); // 先过 a,再过 b
}
}于是 new AndCriteria(male, new OrCriteria(admin, vip)) 这样的嵌套表达式就能描述“男 且 (管理员 或 VIP)”。下面的组合器让你切换 AND/OR/NOT,观察结果集如何随布尔逻辑变化。
正在加载交互实验...
正在加载概念检查...
与现代语言特性的关系
在支持一等函数的语言里,过滤器模式常常“退化”成更轻的形式:一个 Predicate<T> 加上 and()、or()、negate()。Java 的 Stream.filter(Predicate)、C# 的 LINQ、JavaScript 的 Array.filter 都是同一思想的语言级体现。
理解这个模式,能帮你在“写一堆类”和“传一个 lambda”之间做出合适选择:规则复杂、需要复用与测试时做成对象;一次性的简单判断直接用 lambda。
正在加载概念检查...
正在加载本节练习...