当前位置: 首页 > news >正文

【设计模式】深入理解Python中的过滤器模式(Filter Pattern)

深入理解Python中的过滤器模式(Filter Pattern)

在软件设计中,面对复杂的数据处理需求时,我们常常需要从一组数据中筛选出符合特定条件的子集。**过滤器模式(Filter Pattern)**是一种能够简化这种操作的设计模式。它通过将过滤逻辑与对象的业务逻辑分离,使得数据过滤过程更加灵活、可扩展。

本文将详细探讨过滤器模式的概念、应用场景、实现步骤,并通过代码示例演示如何在Python中实现过滤器模式。

1. 什么是过滤器模式?

过滤器模式是一种行为型设计模式,允许用户通过一组标准对对象集合进行筛选。它使用多个标准进行过滤,并提供了一个组合的方式来对数据进行选择。

过滤器模式的核心要点

  • 目标对象:需要过滤的对象集合。
  • 过滤器接口:定义过滤操作的接口,通常有一个或多个方法,用于执行具体的过滤逻辑。
  • 具体过滤器:实现过滤器接口的具体过滤器,包含过滤条件。
  • 上下文(Context):用于管理目标对象和过滤器的类,负责应用过滤器以获取过滤结果。

UML 类图表示

+---------------------+
|      Client         |
+---------------------+||V
+---------------------+
|       Context       |
+---------------------+
| +add_filter()       |
| +filter()           |
+---------------------+||V
+---------------------+
|   Filter Interface   |
+---------------------+
| +filter()           |
+---------------------+||
+---------------------+
|  Concrete Filter    |
+---------------------+
| +filter()           |
+---------------------+

2. 过滤器模式的应用场景

过滤器模式适用于以下场景:

  1. 需要动态筛选对象集合:当对象集合中有多种属性需要筛选时,过滤器模式提供了一种灵活的方式来组合多个过滤条件。
  2. 系统需要支持多种过滤标准:在数据处理过程中,可能需要根据不同的条件进行过滤,使用过滤器模式可以轻松实现这一点。
  3. 复杂业务逻辑与过滤逻辑分离:过滤器模式能够将过滤逻辑与具体的业务逻辑分开,使得代码更易于维护和扩展。

典型应用场景

  • 用户过滤:在用户管理系统中,根据用户角色、状态等多个属性过滤用户列表。
  • 商品筛选:在电商平台中,根据价格、类别、品牌等条件筛选商品。
  • 数据处理:在数据分析和处理过程中,根据多个条件对数据集进行筛选。

3. Python 实现过滤器模式

接下来,我们将通过一个具体的例子来实现过滤器模式。假设我们需要处理一组用户对象,并根据不同的条件进行过滤(如按年龄和性别过滤)。

3.1 定义用户类

首先,我们定义一个 User 类,表示用户对象。

class User:def __init__(self, name, gender, age):self.name = nameself.gender = genderself.age = agedef __repr__(self):return f"User(name={self.name}, gender={self.gender}, age={self.age})"

3.2 定义过滤器接口

接下来,定义一个过滤器接口,声明过滤方法。

from abc import ABC, abstractmethod# 过滤器接口
class Filter(ABC):@abstractmethoddef filter(self, users):pass

3.3 实现具体过滤器

我们实现具体的过滤器来根据年龄和性别过滤用户。

# 按年龄过滤用户
class AgeFilter(Filter):def __init__(self, age):self.age = agedef filter(self, users):return [user for user in users if user.age >= self.age]# 按性别过滤用户
class GenderFilter(Filter):def __init__(self, gender):self.gender = genderdef filter(self, users):return [user for user in users if user.gender == self.gender]

3.4 定义上下文类

定义一个上下文类,用于管理用户集合和应用过滤器。

class UserFilter:def __init__(self):self.filters = []def add_filter(self, filter):self.filters.append(filter)def filter(self, users):filtered_users = usersfor filter in self.filters:filtered_users = filter.filter(filtered_users)return filtered_users

3.5 测试过滤器模式

最后,我们创建用户列表,并使用过滤器模式来筛选用户。

# 创建用户列表
users = [User("Alice", "Female", 30),User("Bob", "Male", 24),User("Charlie", "Male", 35),User("Diana", "Female", 28),User("Ethan", "Male", 22)
]# 使用过滤器模式
user_filter = UserFilter()# 添加过滤器
user_filter.add_filter(AgeFilter(25))  # 年龄过滤
user_filter.add_filter(GenderFilter("Male"))  # 性别过滤# 过滤用户
filtered_users = user_filter.filter(users)
print("Filtered Users:", filtered_users)

输出结果:

Filtered Users: [User(name=Charlie, gender=Male, age=35)]

在这个例子中,我们通过组合不同的过滤器实现了对用户列表的灵活筛选。用户过滤器先应用年龄过滤,再应用性别过滤,最终得到了符合条件的用户列表。

4. 过滤器模式的优缺点

优点

  1. 灵活性:通过组合不同的过滤器,可以轻松实现复杂的过滤逻辑。
  2. 代码重用:过滤器可以被复用,在不同的场合下进行组合使用。
  3. 易于扩展:如果需要增加新的过滤条件,只需添加新的过滤器类,无需修改已有代码。

缺点

  1. 性能开销:如果过滤器较多,过滤链条较长,可能会增加性能开销。
  2. 复杂性:在某些情况下,过多的过滤器可能会使代码变得复杂,增加理解和维护的难度。

5. 改进过滤器模式:使用链式调用

在Python中,我们可以对过滤器模式进行改进,支持链式调用,使得代码更加简洁和流畅。

class ChainedFilter(Filter):def __init__(self):self.filters = []def add_filter(self, filter):self.filters.append(filter)return self  # 支持链式调用def filter(self, users):filtered_users = usersfor filter in self.filters:filtered_users = filter.filter(filtered_users)return filtered_users

使用链式调用的方式构建过滤器:

# 创建链式过滤器
chained_filter = ChainedFilter()
chained_filter.add_filter(AgeFilter(25)).add_filter(GenderFilter("Female"))# 过滤用户
filtered_users = chained_filter.filter(users)
print("Filtered Users (Chained):", filtered_users)

这种改进方式使得过滤器的使用更加灵活,便于构建复杂的过滤条件。

6. 结论

过滤器模式是一种非常有用的设计模式,尤其适合在需要从大量数据中进行条件筛选的场合。通过将过滤逻辑与业务逻辑分离,过滤器模式能够提供一种灵活的方式来组合和应用多个过滤条件。

在Python中,利用类和继承的特性,我们可以简单而高效地实现过滤器模式。希望本文能够帮助你更深入地理解过滤器模式,并能够灵活运用到实际开发中。

如果你有任何问题或建议,欢迎在评论区讨论!

相关文章:

【设计模式】深入理解Python中的过滤器模式(Filter Pattern)

深入理解Python中的过滤器模式(Filter Pattern) 在软件设计中,面对复杂的数据处理需求时,我们常常需要从一组数据中筛选出符合特定条件的子集。**过滤器模式(Filter Pattern)**是一种能够简化这种操作的设…...

vue的动态组件 keep-alive

1. 什么是动态组件 动态组件指的是 动态切换组件的显示与隐藏 2. 如何实现动态组件渲染 vue提供了一个内置的<component>组件&#xff0c;专门用来实现动态组件的渲染。 作用&#xff1a;组件的占位符is的值表示要渲染的组件 示例代码如下&#xff1a; Left.vue的代…...

现代框架开发官网

一、项目背景 维护过 灵犀官网、企业邮官网、免费邮官网 均使用 jquery webpack多页面打包的方式 开发起来较为繁琐 新的官网项目&#xff0c;想使用现代前端框架&#xff0c;但SPA应用不利于SEO 使用SSR方案又依赖运维&#xff0c;增加维护和沟通成本 二、SSG vs 预渲染 S…...

一篇文章快速认识YOLO11 | 关键改进点 | 安装使用 | 模型训练和推理

前言 本文分享YOLO11的关键改进点、性能对比、安装使用、模型训练和推理等内容。 YOLO11 是 Ultralytics 最新的实时目标检测器&#xff0c;凭借更高的精度、速度和效率重新定义了可能性。 除了传统的目标检测外&#xff0c;YOLO11 还支持目标跟踪、实例分割、姿态估计、OBB…...

AtCoder Beginner Contest 375(A,B,C,D,E,F)(大模拟,前缀和,dp,离线处理,Floyd)

比赛链接 AtCoder Beginner Contest 375 A题 代码 #pragma GCC optimize("O2") #pragma GCC optimize("O3") #include <bits/stdc.h> using namespace std; #define int long long const int N 2e5 5, M 1e6 5; const int inf 0x3f3f3f3f3f…...

认识maven

什么是 Maven&#xff1f; Maven 是一个开源的项目管理工具&#xff0c;主要用于 Java 项目的构建、依赖管理和项目生命周期管理。它提供了一种标准的项目结构和管理流程&#xff0c;使得开发人员能够更轻松地管理项目的构建过程&#xff0c;提高代码的可重用性和可维护性。 …...

OSINT技术情报精选·2024年10月第2周

OSINT技术情报精选2024年10月第2周 2024.10.16版权声明&#xff1a;本文为博主chszs的原创文章&#xff0c;未经博主允许不得转载。 1、亿欧智库&#xff1a;《2024中国高精定位服务产业白皮书》 报告的主要内容如下&#xff1a; 产业背景&#xff1a;在“北斗”发展态势的…...

中企通信赋能中信戴卡入选工信部颁发的2023年工业互联网试点示范名单

2024年10月17日&#xff0c;北京-随着工业互联网的迅猛发展&#xff0c;网络安全已成为国家关注的重点议题之一。日前&#xff0c;工业和信息化部&#xff08;工信部&#xff09;公布了2023年工业互联网试点示范名单&#xff0c;中企网络通信技术有限公司&#xff08;简称“中企…...

【C语言】函数的声明与定义

函数的声明 用户自定义函数需要在main函数之前进行声明&#xff0c;用分号结尾。 函数的定义 用户自定义函数在main函数之后进行定义&#xff0c;需要写出具体形参的变量名。注意函数的返回值和返回值类型要一一对应。 函数的调用 调用时&#xff0c;直接使用函数名进行调用&am…...

游戏如何应对薅羊毛问题

在大众眼里&#xff0c;“薅羊毛”是指在电商领域&#xff0c;“羊毛党”利用平台、商家的促销规则&#xff0c;低价获取商品和服务的行为。如前不久“小天鹅被一夜薅走7000万”的案例震惊全网。 然而实际上&#xff0c;“薅羊毛”现象不仅存在于电商场景&#xff0c;在游戏中…...

Chromium html<script>对应c++接口定义

<script>&#xff1a;脚本元素 <script> 元素用于嵌入可执行代码或数据&#xff0c;这通常用作嵌入或者引用 JavaScript 代码。<script> 元素也能在其他语言中使用&#xff0c;比如 WebGL 的 GLSL 着色器语言和 JSON。 更多参考&#xff1a;<script>&…...

ollama + fastgpt+m3e本地部署

ollama fastgptm3e本地部署 开启WSL更新wsl安装ubuntu docker下载修改docker镜像源开启WSL integration 安装fastgpt先创建一个文件夹来放置一些配置文件用命令下载fastgpt配置文件用命令下载docker的部署文件 启动容器M3E下载ollama下载oneapi配置登录oneapi配置ollama渠道配…...

Linux执行source /etc/profile命令报错:权限不够问(已解决)

1.问题 明明以root账号登录Linux系统&#xff0c;在终端执行命令source /etc/profile时 显示权限不够 如下图&#xff1a; 2.问题原因 可能在编辑 /etc/profile 这个文件时不小心把开头的 井号 ‘#’ 给删除了 如图&#xff1a; 这里一定要有# 3.解决办法 进入/etc/pro…...

Windows 11开发全解析

Windows 11开发全解析 一、搭建开发环境 在开始Windows 11开发之前&#xff0c;搭建一个高效的开发环境是至关重要的。Windows 11提供了多种工具和框架&#xff0c;可以帮助开发者快速搭建起一个强大的开发环境。 1. Visual Studio 2024 Visual Studio 2024是微软为Windows…...

如何进行数学家式的学习思考?

如何进行数学家式的学习思考&#xff1f; 学生阶段的数学学习是非常重要的&#xff0c;对这一点很少有人质疑。一提起数学学习&#xff0c;一些学生、家长甚至一些教师认为&#xff0c;学生的数学学习往往侧重于掌握基本概念、公式和解题技巧&#xff0c;通过做题来巩固知识和提…...

自定义类型--结构体

目录 1. 结构体类型的声明 1.1结构的声明 1.2 结构体变量的创建和初始化 1.3不完全结构体 1.4结构的⾃引⽤ 2 结构体的内存对齐 2.1offsetof 2.2 对⻬规则 2.3 为什么存在内存对⻬? 2.4修改默认对⻬数 3. 结构体传参 4 结构体实现位段 4.1什么是位段 4.2 位段的内…...

笔试练习day7

目录 OR59 字符串中找出连续最长的数字串题目解析解法(双指针遍历)代码 NC109 岛屿数量题目解析解法代码(dfs)dfs的实现 拼三角题目解析解法(枚举)代码 感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接 &#x1f412;&#x1f412;&#x1f412; 个人主页 &…...

python 爬虫 入门 一、基础工具

目录 一&#xff0c;网页开发者工具的使用 二、通过python发送请求 &#xff08;一&#xff09;、get &#xff08;二&#xff09;、带参数的get &#xff08;三&#xff09;、post 后续&#xff1a;数据解析 一&#xff0c;网页开发者工具的使用 我们可以用 requests 库…...

金融衍生品中的风险对冲策略分析

金融衍生品是现代金融市场中不可或缺的一部分&#xff0c;它们通过标的资产的价格波动为投资者提供了多样的风险管理工具。随着市场的不确定性和复杂性增加&#xff0c;风险对冲成为企业和个人投资者的首要任务。本文将深入探讨金融衍生品中的常见风险对冲策略&#xff0c;分析…...

linux下建立软链接

深度学习训练中经常会遇到数据量庞大或者工程中模型报错太多导致磁盘空间不够&#xff0c;但是又不想修改原来在代码中写的路径&#xff0c;这个时候制作软连接很有作用&#xff0c;把占用量大的目录移到别的空闲磁盘&#xff0c;然后在原来的目录做一个软连接指向那个移到的空…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...