【设计模式】其它经典模式-规格模式(Specification Pattern)
·
规格模式(Specification Pattern)(C++ 实现)
规格模式(Specification Pattern)是一种行为设计模式,用于将业务规则封装成可重用的逻辑单元,支持通过组合方式构建复杂查询条件。核心思想是将条件判断逻辑抽象为独立对象,实现解耦和灵活组合。
核心组件
ISpecification接口
定义isSatisfiedBy方法,验证对象是否满足条件- 具体规格类
实现特定业务规则(如价格、类别等) - 组合规格类
实现逻辑组合(AND/OR/NOT) - 客户端
组合规格对象进行业务判断
C++ 实现示例
场景:电商产品过滤系统
根据价格、类别、库存等条件筛选产品
#include <iostream>
#include <vector>
#include <string>
#include <memory>
// 1. 产品类
class Product {
public:
Product(std::string name, double price, std::string category, int stock)
: name(name), price(price), category(category), stock(stock) {}
std::string getName() const { return name; }
double getPrice() const { return price; }
std::string getCategory() const { return category; }
int getStock() const { return stock; }
private:
std::string name;
double price;
std::string category;
int stock;
};
// 2. 规格接口
template <typename T>
class ISpecification {
public:
virtual ~ISpecification() = default;
virtual bool isSatisfiedBy(const T& item) const = 0;
};
// 3. 具体规格实现
// 价格规格
class PriceSpecification : public ISpecification<Product> {
public:
PriceSpecification(double minPrice, double maxPrice)
: minPrice(minPrice), maxPrice(maxPrice) {}
bool isSatisfiedBy(const Product& item) const override {
return item.getPrice() >= minPrice && item.getPrice() <= maxPrice;
}
private:
double minPrice;
double maxPrice;
};
// 类别规格
class CategorySpecification : public ISpecification<Product> {
public:
explicit CategorySpecification(std::string category)
: category(std::move(category)) {}
bool isSatisfiedBy(const Product& item) const override {
return item.getCategory() == category;
}
private:
std::string category;
};
// 库存规格
class StockSpecification : public ISpecification<Product> {
public:
explicit StockSpecification(int minStock) : minStock(minStock) {}
bool isSatisfiedBy(const Product& item) const override {
return item.getStock() >= minStock;
}
private:
int minStock;
};
// 4. 组合规格 (AND)
template <typename T>
class AndSpecification : public ISpecification<T> {
public:
AndSpecification(std::shared_ptr<ISpecification<T>> left,
std::shared_ptr<ISpecification<T>> right)
: left(std::move(left)), right(std::move(right)) {}
bool isSatisfiedBy(const T& item) const override {
return left->isSatisfiedBy(item) && right->isSatisfiedBy(item);
}
private:
std::shared_ptr<ISpecification<T>> left;
std::shared_ptr<ISpecification<T>> right;
};
// 5. 组合规格 (OR)
template <typename T>
class OrSpecification : public ISpecification<T> {
public:
OrSpecification(std::shared_ptr<ISpecification<T>> left,
std::shared_ptr<ISpecification<T>> right)
: left(std::move(left)), right(std::move(right)) {}
bool isSatisfiedBy(const T& item) const override {
return left->isSatisfiedBy(item) || right->isSatisfiedBy(item);
}
private:
std::shared_ptr<ISpecification<T>> left;
std::shared_ptr<ISpecification<T>> right;
};
// 6. 使用示例
int main() {
// 创建产品列表
std::vector<Product> products = {
{"Laptop", 1200.0, "Electronics", 5},
{"Book", 15.99, "Books", 20},
{"Headphones", 99.99, "Electronics", 0},
{"Monitor", 250.0, "Electronics", 8},
{"Coffee Mug", 8.5, "Kitchen", 30}
};
// 创建规格对象
auto electronicsSpec = std::make_shared<CategorySpecification>("Electronics");
auto priceSpec = std::make_shared<PriceSpecification>(100.0, 300.0);
auto stockSpec = std::make_shared<StockSpecification>(5);
// 组合规格:电子类 AND (价格在$100-$300之间 OR 库存>5)
auto complexSpec = std::make_shared<AndSpecification<Product>>(
electronicsSpec,
std::make_shared<OrSpecification<Product>>(priceSpec, stockSpec)
);
// 应用规格过滤
std::cout << "Filtered Products:\n";
for (const auto& product : products) {
if (complexSpec->isSatisfiedBy(product)) {
std::cout << "- " << product.getName()
<< " ($" << product.getPrice()
<< ", Stock: " << product.getStock() << ")\n";
}
}
return 0;
}
输出结果
Filtered Products:
- Monitor ($250, Stock: 8)
模式优势
- 解耦业务规则
将条件判断从业务逻辑中分离 - 可重用性
规格对象可在不同场景复用 - 灵活组合
通过 AND/OR/NOT 构建复杂查询 - 可测试性
每个规格可独立测试 - 扩展性
新增规格不影响现有代码
适用场景
- 复杂条件过滤系统
- 验证规则需要动态组合
- 数据库查询条件构建
- 需要高度可配置的业务规则
- 领域驱动设计(DDD)中的规范模式
对比传统方法
| 传统 if-else 方式 | 规格模式 |
|---|---|
| 条件逻辑与业务代码耦合 | 业务规则独立封装 |
| 修改条件需改动核心逻辑 | 通过组合新规格扩展 |
| 复杂条件可读性差 | 声明式组合,逻辑清晰 |
| 重复条件难以复用 | 规格对象全局复用 |
推荐阅读
更多推荐



所有评论(0)