跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava算法

设计模式实战:过滤器模式(Criteria Pattern)详解

过滤器模式(Criteria Pattern)是一种行为型设计模式,允许使用不同标准过滤一组对象。通过实现 Criteria 接口定义筛选条件,可组合多个标准获得单一标准。示例展示了如何创建 Person 实体类,定义性别与婚姻状态的具体筛选器,并利用 AndCriteria 和 OrCriteria 组合逻辑。这种解耦方式便于灵活扩展新规则,适用于复杂业务场景下的数据过滤需求。

dehua dong发布于 2025/1/17更新于 2026/7/2544 浏览
设计模式实战:过滤器模式(Criteria Pattern)详解

设计模式实战:过滤器模式(Criteria Pattern)详解

在开发中,我们经常需要根据不同的条件从集合中筛选出特定的数据。如果每次都要写一堆 if-else,代码会变得难以维护。过滤器模式(Filter Pattern),也叫标准模式(Criteria Pattern),提供了一种解耦的方式,让我们能用不同的标准来过滤对象,并且可以通过逻辑运算把这些标准组合起来。

核心思路

这个模式的核心在于定义一个 Criteria 接口,所有具体的筛选条件都实现它。这样我们就可以灵活地创建任意数量的筛选类,甚至编写组合筛选类(比如'既是男性又是单身')。最终返回的都是筛选过的数据列表。

代码实现

下面是一个完整的 Java 示例,展示了如何构建这套机制。

1. 定义实体类

首先需要一个被筛选的对象,这里用 Person 代表。包含姓名、性别和婚姻状态。

import java.util.ArrayList;
import java.util.List;

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;
    }

    @Override
    public String toString() {
        return "Person{name='" + name + "', gender='" + gender + "', maritalStatus='" + maritalStatus + "'}";
    }

    public String getName() { return name; }
    public String getGender() { return gender; }
    public String getMaritalStatus() { return maritalStatus; }
}

2. 定义 Criteria 接口

这是过滤器的契约,接收一组对象,返回满足条件的子集。

interface Criteria {
    List<Person> meetCriteria(List<Person> persons);
}

3. 具体筛选条件

我们可以为性别、婚姻状态分别实现具体的筛选逻辑。注意这里使用了 equalsIgnoreCase 来处理大小写问题。

class CriteriaMale implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> malePerson = new ArrayList<>();
        for (Person person : persons) {
            if (person.getGender().equalsIgnoreCase("male")) {
                malePerson.add(person);
            }
        }
        return malePerson;
    }
}

class CriteriaFemale implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> femalePerson = new ArrayList<>();
        for (Person person : persons) {
            if (person.getGender().equalsIgnoreCase("female")) {
                femalePerson.add(person);
            }
        }
        return femalePerson;
    }
}

class CriteriaSingle implements Criteria {
    @Override
    public List<Person> meetCriteria(List<Person> persons) {
        List<Person> filteredList = new ArrayList<>();
        for (Person person : persons) {
            if (person.getMaritalStatus().equalsIgnoreCase("single")) {
                filteredList.add(person);
            }
        }
        return filteredList;
    }
}

4. 组合筛选逻辑

这才是模式的精髓。我们可以把两个标准组合成'且'或'或'的关系。

AndCriteria:需要同时满足两个条件。先应用第一个条件,再对结果应用第二个条件。

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);
    }
}

OrCriteria:满足其中一个就行。分别获取两个条件的结果,然后合并去重。

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> firstCriteriaPersons = criteria.meetCriteria(persons);
        List<Person> otherCriteriaPersons = otherCriteria.meetCriteria(persons);
        
        // 合并结果,避免重复添加同一个对象实例
        for (Person otherPerson : otherCriteriaPersons) {
            if (!firstCriteriaPersons.contains(otherPerson)) {
                firstCriteriaPersons.add(otherPerson);
            }
        }
        return firstCriteriaPersons;
    }
}

5. 测试运行

最后我们在主方法里组装这些标准并验证结果。可以看到,通过组合 OrCriteria,我们轻松实现了'男性或单身'的复杂查询。

public static void main(String[] args) {
    List<Person> persons = new ArrayList<>();
    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 single = new CriteriaSingle();
    Criteria singleOrMale = new OrCriteria(male, single);

    System.out.println("-----------------");
    System.out.println("All Males:");
    for (Person item : male.meetCriteria(persons)) {
        System.out.println(item);
    }

    System.out.println("-----------------");
    System.out.println("All Singles:");
    for (Person item : single.meetCriteria(persons)) {
        System.out.println(item);
    }

    System.out.println("-----------------");
    System.out.println("Singles OR Males:");
    List<Person> result = singleOrMale.meetCriteria(persons);
    for (Person person : result) {
        System.out.println(person);
    }
}

总结

通过这种方式,我们将筛选逻辑与业务代码分离开来。如果需要新增一种筛选规则,只需实现 Criteria 接口即可,无需修改现有代码。这种开闭原则的应用,让系统在面对需求变更时更加健壮。

目录

  1. 设计模式实战:过滤器模式(Criteria Pattern)详解
  2. 核心思路
  3. 代码实现
  4. 1. 定义实体类
  5. 2. 定义 Criteria 接口
  6. 3. 具体筛选条件
  7. 4. 组合筛选逻辑
  8. 5. 测试运行
  9. 总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • OpenClaw 2026.3.3 新增 AI 解析 PDF 功能实测
  • OpenClaw:AI 代理框架如何重塑产品思维与工作流程
  • C++ Boost 搜索引擎数据清洗与解析实现详解
  • Webnovel Writer:基于 Claude Code 的长篇网文 AI 创作系统
  • 低成本运行 Claude Code:通过 LiteLLM 接入 GitHub Copilot Chat API
  • 智能梯控系统设计方案:跨品牌群控与 AI 调度架构解析
  • GESP C++ 一级真题解析:手机电量显示
  • Angular入门启蒙03,Angular 环境搭建全解析:Node.js、npm 与 Angular CLI 安装配置
  • C++ multiset 核心原理与实战指南
  • 绿联 NAS 配置 WebDAV 公网访问及 RaiDrive 挂载指南
  • Windows 本地部署 ComfyUI 运行 Qwen-Image 大模型详细步骤
  • STM32 中__weak 弱定义函数核心总结
  • 第十五届蓝桥杯 Python B 组省赛真题解析
  • 磨损均衡算法介绍
  • OpenAI Whisper 语音识别与转录使用指南
  • VS Code 中 GitHub Copilot 安装配置与高阶使用指南
  • 自然科学领域机器学习与深度学习:从数据预处理到时空建模
  • 蓝桥杯 2025 省赛 Python B 组题目解析
  • WebP 图像格式:原理、特性与实战应用
  • 微信小程序 WebView 与 H5 页面双向通信实战指南

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online