设计模式 | 过滤器模式
过滤器模式(Filter Pattern) 是结构型设计模式中的筛选专家,它允许开发人员使用不同的标准来过滤一组对象,并通过逻辑运算以解耦的方式组合这些标准。本文将深入探索过滤器模式的核心思想、实现技巧以及在C++中的高效实践,解决复杂数据筛选问题。
为什么需要过滤器模式?
在软件开发中,我们经常面临复杂的数据筛选需求:
-
电子商务中的商品筛选(价格、类别、评分)
-
人力资源系统中的候选人过滤(技能、经验、学历)
-
数据分析中的数据集过滤(时间范围、数值区间、类别)
-
日志系统中的事件过滤(级别、来源、关键词)
传统筛选方式的问题:
-
条件硬编码:筛选逻辑与业务代码紧耦合
-
组合复杂度:多条件组合导致代码臃肿
-
可扩展性差:新增筛选条件需要修改核心逻辑
-
复用性低:相似筛选逻辑无法复用
过滤器模式通过解耦筛选标准与筛选逻辑解决了这些问题,提供了灵活的数据筛选方案。
过滤器模式的核心概念
模式结构解析
[客户端] → [过滤器接口] → [具体过滤器]↑[逻辑组合过滤器]
关键角色定义
-
被过滤对象(Object)
-
需要被筛选的数据对象
-
-
过滤器接口(Filter)
-
定义过滤操作的通用接口
-
-
具体过滤器(Concrete Filter)
-
实现特定过滤标准
-
-
组合过滤器(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")));
};
过滤器模式的五大优势
-
解耦筛选逻辑
// 业务代码不依赖具体筛选实现 void processCandidates(Filter* filter) {auto filtered = filter->filter(candidates);// 处理筛选结果 }
-
动态组合条件
// 运行时构建筛选条件 auto filter = userRequestedFilter(); // 根据用户输入创建 auto results = filter->filter(data);
-
扩展性强
// 新增筛选条件 class NewConditionFilter : public Filter {// 实现新条件筛选 };
-
复用性高
// 相同筛选器多处使用 auto highRatingFilter = std::make_shared<RatingFilter>(4.5); auto products1 = highRatingFilter->filter(electronics); auto products2 = highRatingFilter->filter(books);
-
简化复杂逻辑
// 复杂逻辑清晰表达 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;}
};
总结
过滤器模式是处理数据筛选需求的优雅解决方案,它通过:
-
逻辑解耦:分离筛选标准与业务逻辑
-
灵活组合:支持AND/OR/NOT等逻辑运算
-
易于扩展:新增筛选器不影响现有代码
-
提高复用:筛选器可多场景复用
-
清晰表达:复杂筛选条件直观表达
使用时机:
-
需要根据多种标准过滤对象集合
-
筛选条件需要灵活组合
-
筛选逻辑可能频繁变化
-
需要避免硬编码筛选条件
-
系统需要支持动态筛选条件
"过滤器模式不是简单地筛选数据,而是构建数据处理的管道。它是面向对象设计中处理复杂筛选需求的优雅方案。" - 设计模式实践者