目录
- 过滤器模式简介
- 过滤器模式的结构
- 过滤器模式的优缺点
- 过滤器模式的实现
- 4.1 Python 示例
- 过滤器模式的应用场景
- 出站链接
- 站内链接
- 参考资料
1. 过滤器模式简介
过滤器模式(Filter Pattern),又称标准模式(Criteria Pattern),是一种结构型设计模式,用于对集合对象进行过滤,并返回符合特定标准的子集。
为什么使用过滤器模式?
- 数据筛选:应用于大量数据的筛选,如电商商品筛选、用户权限管理、日志过滤等。
- 提高代码复用性:避免在业务逻辑中硬编码筛选规则,使筛选逻辑可复用、可扩展。
- 支持动态组合:多个过滤器可以组合,形成复杂的筛选逻辑。
典型应用
- 电商平台:按价格、品牌、销量、评分筛选商品
- 用户管理系统:按角色、权限、状态筛选用户
- 日志分析:按日志级别(INFO、WARNING、ERROR)过滤日志
2. 过滤器模式的结构
过滤器模式主要包含以下三个核心角色:
角色 | 作用 |
---|---|
Criteria(标准/过滤器接口) | 定义 filter() 方法,实现筛选逻辑 |
ConcreteCriteria(具体标准) | 实现 filter() ,对集合进行筛选 |
Criteria组合(多个标准组合) | 通过 AND、OR 组合多个过滤器 |
UML 类图
┌───────────────────────────┐
│ Criteria │ (标准接口)
│ + filter(items): list │
└──────────▲───────────────┘
│
┌───────────────────────────┐
│ ConcreteCriteria │ (具体标准)
│ + filter(items): list │
└───────────────────────────┘
│
┌───────────────────────────┐
│ CompositeCriteria (AND/OR) │ (组合标准)
│ + filter(items): list │
└───────────────────────────┘
3. 过滤器模式的优缺点
✅ 优点
- 代码可扩展:可以新增标准,而不修改已有代码(符合开闭原则 OCP)。
- 支持动态组合:不同标准可以自由组合,形成复杂的筛选逻辑。
- 提高代码复用性:标准可以在多个地方使用,避免重复代码。
❌ 缺点
- 可能影响性能:对大数据集合进行过滤时,多个标准组合可能影响性能。
- 增加代码复杂度:多个标准的组合可能导致代码结构较复杂。
4. 过滤器模式的实现
4.1 Python 示例
场景:我们有一个用户列表,需要按性别、年龄范围、VIP 会员进行筛选,并支持组合筛选(如男性 AND VIP)。
# 1. 定义标准接口
class Criteria:
def filter(self, persons):
pass
# 2. 具体标准类
class MaleCriteria(Criteria):
def filter(self, persons):
return [p for p in persons if p.gender == "Male"]
class FemaleCriteria(Criteria):
def filter(self, persons):
return [p for p in persons if p.gender == "Female"]
class VIPCriteria(Criteria):
def filter(self, persons):
return [p for p in persons if p.is_vip]
class AgeCriteria(Criteria):
def __init__(self, min_age, max_age):
self.min_age = min_age
self.max_age = max_age
def filter(self, persons):
return [p for p in persons if self.min_age <= p.age <= self.max_age]
# 3. 组合标准类(AND 和 OR)
class AndCriteria(Criteria):
def __init__(self, criteria1, criteria2):
self.criteria1 = criteria1
self.criteria2 = criteria2
def filter(self, persons):
return self.criteria2.filter(self.criteria1.filter(persons))
class OrCriteria(Criteria):
def __init__(self, criteria1, criteria2):
self.criteria1 = criteria1
self.criteria2 = criteria2
def filter(self, persons):
return list(set(self.criteria1.filter(persons) + self.criteria2.filter(persons)))
# 4. 用户类
class Person:
def __init__(self, name, gender, age, is_vip):
self.name = name
self.gender = gender
self.age = age
self.is_vip = is_vip
def __repr__(self):
return f"{self.name} ({self.gender}, {self.age}, {'VIP' if self.is_vip else 'Regular'})"
# 5. 创建用户列表
users = [
Person("Alice", "Female", 25, True),
Person("Bob", "Male", 30, False),
Person("Charlie", "Male", 35, True),
Person("Diana", "Female", 22, False),
Person("Eve", "Female", 29, True),
Person("Frank", "Male", 28, True),
]
# 6. 使用过滤器
male_criteria = MaleCriteria()
vip_criteria = VIPCriteria()
age_criteria = AgeCriteria(25, 30)
male_vip_criteria = AndCriteria(male_criteria, vip_criteria)
age_or_vip_criteria = OrCriteria(age_criteria, vip_criteria)
print("Male Users:", male_criteria.filter(users))
print("VIP Users:", vip_criteria.filter(users))
print("Male VIP Users:", male_vip_criteria.filter(users))
print("Users (Age 25-30 OR VIP):", age_or_vip_criteria.filter(users))
输出结果:
Male Users: [Bob (Male, 30, Regular), Charlie (Male, 35, VIP), Frank (Male, 28, VIP)]
VIP Users: [Alice (Female, 25, VIP), Charlie (Male, 35, VIP), Eve (Female, 29, VIP), Frank (Male, 28, VIP)]
Male VIP Users: [Charlie (Male, 35, VIP), Frank (Male, 28, VIP)]
Users (Age 25-30 OR VIP): [Alice (Female, 25, VIP), Charlie (Male, 35, VIP), Eve (Female, 29, VIP), Frank (Male, 28, VIP), Bob (Male, 30, Regular)]
5. 过滤器模式的应用场景
适用于以下情况
- 需要对数据集合进行筛选
- 例如 用户、商品、日志、订单 等数据筛选。
- 需要动态组合筛选条件
- 例如 (性别 = 男 AND 年龄 > 30) OR VIP。
- 希望避免硬编码条件
- 例如 避免
if-else
逻辑混乱,使用独立标准类来管理规则。
- 例如 避免
真实案例
- 电商平台
- 商品筛选(价格范围、品牌、销量、评分)。
- 用户管理系统
- 按角色、权限、状态筛选用户。
- 日志系统
- 按日志级别(INFO、ERROR)、时间范围筛选日志。
6. 出站链接
7. 站内链接
8. 参考资料
- Gamma, E., Design Patterns: Elements of Reusable Object-Oriented Software (1994).
总结
- 过滤器模式适用于数据筛选、用户管理、日志系统等场景。
- 支持动态组合(AND/OR),避免硬编码条件,提高代码复用性。
- 应用广泛,如电商、日志、用户管理等。
如果你有具体的需求,欢迎讨论!🚀
发表回复