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

设计模式 | 过滤器模式

过滤器模式(Filter Pattern) 是结构型设计模式中的筛选专家,它允许开发人员使用不同的标准来过滤一组对象,并通过逻辑运算以解耦的方式组合这些标准。本文将深入探索过滤器模式的核心思想、实现技巧以及在C++中的高效实践,解决复杂数据筛选问题。

为什么需要过滤器模式?

在软件开发中,我们经常面临复杂的数据筛选需求:

  • 电子商务中的商品筛选(价格、类别、评分)

  • 人力资源系统中的候选人过滤(技能、经验、学历)

  • 数据分析中的数据集过滤(时间范围、数值区间、类别)

  • 日志系统中的事件过滤(级别、来源、关键词)

传统筛选方式的问题:

  • 条件硬编码:筛选逻辑与业务代码紧耦合

  • 组合复杂度:多条件组合导致代码臃肿

  • 可扩展性差:新增筛选条件需要修改核心逻辑

  • 复用性低:相似筛选逻辑无法复用

过滤器模式通过解耦筛选标准与筛选逻辑解决了这些问题,提供了灵活的数据筛选方案。

过滤器模式的核心概念

模式结构解析

[客户端] → [过滤器接口] → [具体过滤器]↑[逻辑组合过滤器]

关键角色定义

  1. 被过滤对象(Object)

    • 需要被筛选的数据对象

  2. 过滤器接口(Filter)

    • 定义过滤操作的通用接口

  3. 具体过滤器(Concrete Filter)

    • 实现特定过滤标准

  4. 组合过滤器(Composite Filter)

    • 组合多个过滤器实现逻辑运算

C++实现:人才筛选系统

让我们实现一个人才筛选系统,支持多种条件的灵活组合:

#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
#include <string>// ================= 被过滤对象:候选人 =================
struct Candidate {std::string name;int age;double yearsOfExperience;std::string education;std::vector<std::string> skills;bool isCertified;Candidate(std::string name, int age, double exp, std::string edu, std::vector<std::string> skills, bool certified): name(std::move(name)), age(age), yearsOfExperience(exp),education(std::move(edu)), skills(std::move(skills)), isCertified(certified) {}
};// ================= 过滤器接口 =================
class Filter {
public:virtual ~Filter() = default;virtual std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const = 0;
};// ================= 具体过滤器:年龄过滤器 =================
class AgeFilter : public Filter {
public:explicit AgeFilter(int minAge, int maxAge) : minAge_(minAge), maxAge_(maxAge) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[this](const Candidate& c) {return c.age >= minAge_ && c.age <= maxAge_;});return result;}private:int minAge_;int maxAge_;
};// ================= 具体过滤器:经验过滤器 =================
class ExperienceFilter : public Filter {
public:explicit ExperienceFilter(double minYears) : minYears_(minYears) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[this](const Candidate& c) {return c.yearsOfExperience >= minYears_;});return result;}private:double minYears_;
};// ================= 具体过滤器:教育过滤器 =================
class EducationFilter : public Filter {
public:explicit EducationFilter(std::string requiredEdu) : requiredEdu_(std::move(requiredEdu)) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[this](const Candidate& c) {return c.education == requiredEdu_;});return result;}private:std::string requiredEdu_;
};// ================= 具体过滤器:技能过滤器 =================
class SkillFilter : public Filter {
public:explicit SkillFilter(std::vector<std::string> requiredSkills) : requiredSkills_(std::move(requiredSkills)) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[this](const Candidate& c) {for (const auto& skill : requiredSkills_) {if (std::find(c.skills.begin(), c.skills.end(), skill) == c.skills.end()) {return false;}}return true;});return result;}private:std::vector<std::string> requiredSkills_;
};// ================= 具体过滤器:认证过滤器 =================
class CertificationFilter : public Filter {
public:std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[](const Candidate& c) {return c.isCertified;});return result;}
};// ================= 组合过滤器:逻辑与 =================
class AndFilter : public Filter {
public:AndFilter(std::shared_ptr<Filter> first, std::shared_ptr<Filter> second): first_(std::move(first)), second_(std::move(second)) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {auto filtered = first_->filter(candidates);return second_->filter(filtered);}private:std::shared_ptr<Filter> first_;std::shared_ptr<Filter> second_;
};// ================= 组合过滤器:逻辑或 =================
class OrFilter : public Filter {
public:OrFilter(std::shared_ptr<Filter> first, std::shared_ptr<Filter> second): first_(std::move(first)), second_(std::move(second)) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {auto result1 = first_->filter(candidates);auto result2 = second_->filter(candidates);// 合并结果并去重std::vector<Candidate> result;result.reserve(result1.size() + result2.size());result.insert(result.end(), result1.begin(), result1.end());for (const auto& c : result2) {if (std::find(result.begin(), result.end(), c) == result.end()) {result.push_back(c);}}return result;}private:std::shared_ptr<Filter> first_;std::shared_ptr<Filter> second_;
};// ================= 组合过滤器:逻辑非 =================
class NotFilter : public Filter {
public:explicit NotFilter(std::shared_ptr<Filter> filter): filter_(std::move(filter)) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {auto filtered = filter_->filter(candidates);std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[&filtered](const Candidate& c) {return std::find(filtered.begin(), filtered.end(), c) == filtered.end();});return result;}private:std::shared_ptr<Filter> filter_;
};// ================= 辅助函数:打印候选人 =================
void printCandidates(const std::vector<Candidate>& candidates, const std::string& title) {std::cout << "\n=== " << title << " (" << candidates.size() << ") ===\n";for (const auto& c : candidates) {std::cout << "- " << c.name << " (Age: " << c.age << ", Exp: " << c.yearsOfExperience << " yrs"<< ", Edu: " << c.education<< ", Certified: " << (c.isCertified ? "Yes" : "No") << ")\n";std::cout << "  Skills: ";for (const auto& skill : c.skills) {std::cout << skill << ", ";}std::cout << "\n";}std::cout << "==============================\n";
}// ================= 客户端代码 =================
int main() {// 创建候选人列表std::vector<Candidate> candidates = {Candidate("Alice", 28, 5.5, "Master", {"C++", "Python", "AI"}, true),Candidate("Bob", 32, 8.0, "Bachelor", {"Java", "SQL", "Cloud"}, false),Candidate("Charlie", 25, 3.0, "PhD", {"C++", "ML", "Data Science"}, true),Candidate("Diana", 35, 10.0, "Master", {"C++", "Python", "System Design"}, true),Candidate("Evan", 40, 15.0, "Bachelor", {"C", "Embedded", "Linux"}, false),Candidate("Fiona", 29, 4.5, "Master", {"JavaScript", "React", "Node.js"}, true)};// 创建具体过滤器auto ageFilter = std::make_shared<AgeFilter>(25, 35);auto expFilter = std::make_shared<ExperienceFilter>(5.0);auto eduFilter = std::make_shared<EducationFilter>("Master");auto cppSkillFilter = std::make_shared<SkillFilter>(std::vector<std::string>{"C++"});auto certFilter = std::make_shared<CertificationFilter>();// 基础筛选printCandidates(ageFilter->filter(candidates), "年龄在25-35岁之间的候选人");printCandidates(eduFilter->filter(candidates), "拥有硕士学位的候选人");printCandidates(cppSkillFilter->filter(candidates), "掌握C++技能的候选人");// 组合筛选:年龄在25-35岁且拥有硕士学位auto ageAndEdu = std::make_shared<AndFilter>(ageFilter, eduFilter);printCandidates(ageAndEdu->filter(candidates), "年龄25-35且拥有硕士学位的候选人");// 组合筛选:5年以上经验或拥有认证auto expOrCert = std::make_shared<OrFilter>(expFilter, certFilter);printCandidates(expOrCert->filter(candidates), "5年以上经验或拥有认证的候选人");// 组合筛选:掌握C++技能但没有认证auto cppButNotCert = std::make_shared<AndFilter>(cppSkillFilter,std::make_shared<NotFilter>(certFilter));printCandidates(cppButNotCert->filter(candidates), "掌握C++但没有认证的候选人");// 复杂组合筛选:硕士学历,年龄25-35,掌握C++,有认证auto complexFilter = std::make_shared<AndFilter>(std::make_shared<AndFilter>(ageAndEdu, cppSkillFilter),certFilter);printCandidates(complexFilter->filter(candidates), "复杂筛选结果");return 0;
}

过滤器模式的五大优势

1. 解耦筛选标准

// 筛选逻辑独立于业务代码
class CustomFilter : public Filter {
public:std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {// 自定义筛选逻辑}
};

2. 灵活组合条件

// 任意组合筛选条件
auto filter = std::make_shared<AndFilter>(std::make_shared<OrFilter>(filterA, filterB),std::make_shared<NotFilter>(filterC)
);

3. 易于扩展

// 新增筛选条件无需修改现有代码
class NewFilter : public Filter {// 实现新筛选逻辑
};

4. 提高复用性

// 相同筛选器在不同场景复用
auto masterFilter = std::make_shared<EducationFilter>("Master");
auto candidates1 = masterFilter->filter(techCandidates);
auto candidates2 = masterFilter->filter(managerCandidates);

5. 支持复杂逻辑

// 实现复杂筛选逻辑
auto complexFilter = std::make_shared<OrFilter>(std::make_shared<AndFilter>(filterA, filterB),std::make_shared<AndFilter>(filterC, filterD)
);

过滤器模式的高级应用

1. 动态过滤器构建

class FilterBuilder {
public:FilterBuilder& addFilter(std::shared_ptr<Filter> filter) {filters_.push_back(filter);return *this;}std::shared_ptr<Filter> buildAnd() {if (filters_.empty()) return nullptr;auto result = filters_[0];for (size_t i = 1; i < filters_.size(); ++i) {result = std::make_shared<AndFilter>(result, filters_[i]);}return result;}// 类似实现buildOr等方法private:std::vector<std::shared_ptr<Filter>> filters_;
};// 使用
FilterBuilder builder;
auto filter = builder.addFilter(ageFilter).addFilter(eduFilter).addFilter(cppSkillFilter).buildAnd();

2. 过滤器链

class FilterChain : public Filter {
public:void addFilter(std::shared_ptr<Filter> filter) {filters_.push_back(filter);}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result = candidates;for (const auto& filter : filters_) {result = filter->filter(result);}return result;}private:std::vector<std::shared_ptr<Filter>> filters_;
};// 使用
FilterChain chain;
chain.addFilter(ageFilter);
chain.addFilter(eduFilter);
auto filtered = chain.filter(candidates);

3. 基于策略的过滤器

class StrategyBasedFilter : public Filter {
public:using Strategy = std::function<bool(const Candidate&)>;explicit StrategyBasedFilter(Strategy strategy) : strategy_(std::move(strategy)) {}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result;std::copy_if(candidates.begin(), candidates.end(), std::back_inserter(result),[this](const Candidate& c) {return strategy_(c);});return result;}private:Strategy strategy_;
};// 使用
auto customFilter = std::make_shared<StrategyBasedFilter>([](const Candidate& c) {return c.yearsOfExperience > 5 && c.skills.size() >= 3;}
);

过滤器模式的应用场景

1. 电子商务产品筛选

class ProductFilter : public Filter {
public:// 价格范围过滤class PriceRangeFilter : public Filter {// 实现价格范围筛选};// 类别过滤class CategoryFilter : public Filter {// 实现类别筛选};// 评分过滤class RatingFilter : public Filter {// 实现评分筛选};// 组合使用auto filter = std::make_shared<AndFilter>(std::make_shared<PriceRangeFilter>(100, 500),std::make_shared<OrFilter>(std::make_shared<CategoryFilter>("Electronics"),std::make_shared<CategoryFilter>("Computers")));
};

2. 日志事件过滤系统

class LogFilter : public Filter {
public:// 日志级别过滤class LevelFilter : public Filter {// 实现级别筛选};// 时间范围过滤class TimeRangeFilter : public Filter {// 实现时间范围筛选};// 关键词过滤class KeywordFilter : public Filter {// 实现关键词筛选};// 组合使用auto criticalErrors = std::make_shared<AndFilter>(std::make_shared<LevelFilter>("ERROR"),std::make_shared<KeywordFilter>("critical"));
};

3. 金融交易分析

class TransactionFilter : public Filter {
public:// 交易类型过滤class TypeFilter : public Filter {// 实现交易类型筛选};// 金额范围过滤class AmountRangeFilter : public Filter {// 实现金额范围筛选};// 时间窗口过滤class TimeWindowFilter : public Filter {// 实现时间窗口筛选};// 可疑交易组合筛选auto suspiciousTransactions = std::make_shared<OrFilter>(std::make_shared<AndFilter>(std::make_shared<TypeFilter>("LargeTransfer"),std::make_shared<AmountRangeFilter>(10000, 50000)),std::make_shared<AndFilter>(std::make_shared<TypeFilter>("International"),std::make_shared<TimeWindowFilter>("00:00", "06:00")));
};

过滤器模式的五大优势

  1. 解耦筛选逻辑

    // 业务代码不依赖具体筛选实现
    void processCandidates(Filter* filter) {auto filtered = filter->filter(candidates);// 处理筛选结果
    }
  2. 动态组合条件

    // 运行时构建筛选条件
    auto filter = userRequestedFilter(); // 根据用户输入创建
    auto results = filter->filter(data);
  3. 扩展性强

    // 新增筛选条件
    class NewConditionFilter : public Filter {// 实现新条件筛选
    };
  4. 复用性高

    // 相同筛选器多处使用
    auto highRatingFilter = std::make_shared<RatingFilter>(4.5);
    auto products1 = highRatingFilter->filter(electronics);
    auto products2 = highRatingFilter->filter(books);
  5. 简化复杂逻辑

    // 复杂逻辑清晰表达
    auto filter = std::make_shared<AndFilter>(std::make_shared<OrFilter>(A, B),std::make_shared<NotFilter>(C)
    );

过滤器模式的最佳实践

1. 使用智能指针管理资源

// 安全管理过滤器生命周期
std::shared_ptr<Filter> createFilterChain() {auto chain = std::make_shared<FilterChain>();chain->addFilter(std::make_shared<AgeFilter>(25, 35));chain->addFilter(std::make_shared<EducationFilter>("Master"));return chain;
}

2. 优化筛选性能

// 预先排序或索引优化
class IndexedFilter : public Filter {
public:explicit IndexedFilter(std::shared_ptr<Filter> baseFilter) : baseFilter_(baseFilter) {// 构建索引}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {// 使用索引加速筛选}
};

3. 支持空过滤器

// 空过滤器实现
class NullFilter : public Filter {
public:std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {return candidates; // 返回所有元素}
};// 简化条件判断
std::shared_ptr<Filter> getFilter() {if (noFilterNeeded) {return std::make_shared<NullFilter>();}// 返回实际过滤器
}

4. 过滤器命名规范

// 清晰表达筛选逻辑
class AgeRangeFilter       // 年龄范围筛选
class ExperienceFilter     // 经验筛选
class EducationTypeFilter  // 教育类型筛选
class SkillSetFilter       // 技能集合筛选

过滤器模式与其他模式的关系

模式关系区别
策略模式都封装算法策略改变对象行为,过滤器筛选集合
装饰器模式都使用包装装饰器添加功能,过滤器筛选元素
组合模式都处理树结构组合处理整体-部分,过滤器组合条件
规范模式概念相似规范模式是过滤器模式的理论基础

组合使用示例

// 过滤器 + 工厂模式
class FilterFactory {
public:static std::shared_ptr<Filter> createAgeFilter(int min, int max) {return std::make_shared<AgeFilter>(min, max);}static std::shared_ptr<Filter> createEducationFilter(const std::string& edu) {return std::make_shared<EducationFilter>(edu);}// 其他过滤器创建方法...
};// 客户端使用
auto filter = FilterFactory::createAgeFilter(25, 35);

应用案例

1. 图像处理管道

class ImageFilter : public Filter {
public:// 灰度化过滤器class GrayscaleFilter : public Filter {std::vector<Image> filter(const std::vector<Image>& images) const override {std::vector<Image> result;for (const auto& img : images) {result.push_back(convertToGrayscale(img));}return result;}};// 尺寸调整过滤器class ResizeFilter : public Filter {// 实现尺寸调整};// 滤镜应用class EffectFilter : public Filter {// 实现滤镜效果};// 创建处理管道auto processingPipeline = std::make_shared<FilterChain>();processingPipeline->addFilter(std::make_shared<ResizeFilter>(800, 600));processingPipeline->addFilter(std::make_shared<GrayscaleFilter>());processingPipeline->addFilter(std::make_shared<EffectFilter>("Vintage"));
};

2. 网络安全规则引擎

class SecurityFilter : public Filter {
public:// IP黑名单过滤器class IPBlacklistFilter : public Filter {// 实现IP黑名单筛选};// 异常行为检测class AnomalyDetectionFilter : public Filter {// 实现异常行为检测};// 敏感操作监控class SensitiveOperationFilter : public Filter {// 实现敏感操作监控};// 组合安全规则auto securityRules = std::make_shared<OrFilter>(std::make_shared<IPBlacklistFilter>(),std::make_shared<AndFilter>(std::make_shared<AnomalyDetectionFilter>(),std::make_shared<SensitiveOperationFilter>()));
};

3. 科学数据分析

class DataFilter : public Filter {
public:// 异常值过滤器class OutlierFilter : public Filter {// 实现异常值筛选};// 范围过滤器class RangeFilter : public Filter {// 实现数据范围筛选};// 统计显著性过滤器class SignificanceFilter : public Filter {// 实现统计显著性筛选};// 相关性过滤器class CorrelationFilter : public Filter {// 实现相关性筛选};// 创建分析管道auto analysisPipeline = std::make_shared<FilterChain>();analysisPipeline->addFilter(std::make_shared<OutlierFilter>(3.0)); // 3σanalysisPipeline->addFilter(std::make_shared<RangeFilter>(0.0, 1.0));analysisPipeline->addFilter(std::make_shared<SignificanceFilter>(0.05));analysisPipeline->addFilter(std::make_shared<CorrelationFilter>(0.7));
};

过滤器模式的挑战与解决方案

挑战解决方案
性能问题使用索引、缓存或并行处理
复杂条件优化应用短路评估和条件排序
动态条件生成实现过滤器构建器或DSL
大型数据集分块处理或流式过滤

性能优化示例

class OptimizedAndFilter : public Filter {
public:OptimizedAndFilter(std::vector<std::shared_ptr<Filter>> filters): filters_(std::move(filters)) {// 根据预估选择率排序std::sort(filters_.begin(), filters_.end(), [](const auto& a, const auto& b) {return a->estimatedSelectivity() < b->estimatedSelectivity();});}std::vector<Candidate> filter(const std::vector<Candidate>& candidates) const override {std::vector<Candidate> result = candidates;for (const auto& filter : filters_) {// 如果结果集已很小,提前终止if (result.size() < 10) break;result = filter->filter(result);}return result;}
};

总结

过滤器模式是处理数据筛选需求的优雅解决方案,它通过:

  1. 逻辑解耦:分离筛选标准与业务逻辑

  2. 灵活组合:支持AND/OR/NOT等逻辑运算

  3. 易于扩展:新增筛选器不影响现有代码

  4. 提高复用:筛选器可多场景复用

  5. 清晰表达:复杂筛选条件直观表达

使用时机

  • 需要根据多种标准过滤对象集合

  • 筛选条件需要灵活组合

  • 筛选逻辑可能频繁变化

  • 需要避免硬编码筛选条件

  • 系统需要支持动态筛选条件

"过滤器模式不是简单地筛选数据,而是构建数据处理的管道。它是面向对象设计中处理复杂筛选需求的优雅方案。" - 设计模式实践者

http://www.lryc.cn/news/577075.html

相关文章:

  • MySQL之全场景常用工具链
  • MyBatis批量删除
  • 【系统分析师】2021年真题:案例分析-答案及详解
  • CppCon 2017 学习:Type Punning in C++17 Avoiding Pun-defined Behavior
  • 【硬核数学】2.4 驯服“梯度下降”:深度学习中的优化艺术与正则化技巧《从零构建机器学习、深度学习到LLM的数学认知》
  • Python爬虫:Requests与Beautiful Soup库详解
  • ISP Pipeline(9):Noise Filter for Chroma 色度去噪
  • node js入门,包含express,npm管理
  • 用户行为序列建模(篇八)-【阿里】DIEN
  • ROS常用的路径规划算法介绍
  • 在Linux系统中部署Java项目
  • 爪形行列式
  • 图书管理系统练习项目源码-前后端分离-使用node.js来做后端开发
  • Linux中ssh无法使用配置的环境变量,ssh(非登录环境)环境变量和登录环境变量不同步问题
  • python中多线程:线程插队方法join详解、线程停止、通过变量来让线程停止
  • 电子计数跳绳原型
  • StarRocks 3.5 新特性解读:Snapshot 快照恢复、大导入性能全面升级、分区管理更智能
  • 左神算法之螺旋打印
  • vue使用Element Plus UI框架
  • Modbus 报文结构与 CRC 校验实战指南(一)
  • 设计模式(五)
  • Java面试宝典:基础五
  • pyhton基础【18】面向对象基础一
  • LRU缓存设计与实现详解
  • XWPFDocument导出word文件
  • 使用component封装组件和h函数的用法
  • 71. 简化路径 —day94
  • Utils系列之内存池(Fixed size)
  • Elasticsearch 集群升级实战指引—7.x 升级到 8.x
  • 【C++】C++中的友元函数和友元类