创建型设计模式(Creational Design Patterns)关注对象的创建机制,旨在在不指定具体类的情况下创建对象,提高系统的灵活性和可维护性。C++ 中常见的创建型模式有以下五种:
五种创建型模式对比表
| 模式 |
适用场景 |
C++ 推荐实现要点 |
| 单例 |
全局唯一资源管理 |
Magic Static + delete 拷贝 |
| 工厂方法 |
创建单一产品,延迟到子类 |
虚函数 + unique_ptr |
| 抽象工厂 |
创建产品族 |
多产品接口 + 工厂聚合 |
| 建造者 |
复杂对象分步构建 |
Fluent interface / 链式调用 |
| 原型 |
高成本对象复制 |
clone() + 深拷贝语义 |
1. 单例模式(Singleton)
关键点
- 确保一个类只有一个实例,并提供全局访问点。
- 构造函数私有化,禁止外部直接构造。
- 使用静态成员变量保存唯一实例。
优缺点
| 优点 |
缺点 |
| 节省内存,避免重复创建 |
全局状态,破坏封装性 |
| 提供全局访问点 |
难以测试(依赖全局状态) |
| 控制资源(如日志、配置) |
多线程需额外同步 |
C++ 最佳实现(C++11 起,线程安全)
cpp
复制代码
class Singleton {
public:
static Singleton& getInstance() {
static Singleton instance; // Magic Static,C++11 起线程安全
return instance;
}
// 删除拷贝和赋值(C++11)
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
Singleton() = default; // 私有构造
};
调用方式
cpp
复制代码
auto& s = Singleton::getInstance();
2. 工厂方法模式(Factory Method)
关键点
- 定义创建对象的接口,但让子类决定实例化哪个类。
- 将对象创建延迟到子类。
优缺点
| 优点 |
缺点 |
| 解耦客户端与具体产品 |
类数量增加 |
| 符合开闭原则(新增产品只需加子类) |
每个产品需对应一个工厂子类 |
C++ 实现
cpp
复制代码
// 产品基类
class Product {
public:
virtual ~Product() = default;
virtual void use() = 0;
};
// 具体产品
class ConcreteProductA : public Product {
public:
void use() override { std::cout << "Using A\n"; }
};
// 工厂基类
class Creator {
public:
virtual ~Creator() = default;
virtual std::unique_ptr<Product> createProduct() = 0;
};
// 具体工厂
class ConcreteCreatorA : public Creator {
public:
std::unique_ptr<Product> createProduct() override {
return std::make_unique<ConcreteProductA>();
}
};
调用方式
cpp
复制代码
ConcreteCreatorA factory;
auto product = factory.createProduct();
product->use();
3. 抽象工厂模式(Abstract Factory)
关键点
- 提供一个创建一系列相关或依赖对象的接口,而无需指定具体类。
- 适用于产品族(多个相关产品组合)。
优缺点
| 优点 |
缺点 |
| 保证产品族的一致性 |
增加系统复杂度 |
| 易于切换产品族 |
难以支持新种类产品(违反开闭) |
C++ 实现
cpp
复制代码
// 抽象产品 A 和 B
class AbstractProductA { public: virtual ~AbstractProductA() = default; };
class AbstractProductB { public: virtual ~AbstractProductB() = default; };
// 具体产品
class ProductA1 : public AbstractProductA {};
class ProductB1 : public AbstractProductB {};
// 抽象工厂
class AbstractFactory {
public:
virtual ~AbstractFactory() = default;
virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
};
// 具体工厂
class ConcreteFactory1 : public AbstractFactory {
public:
std::unique_ptr<AbstractProductA> createProductA() override {
return std::make_unique<ProductA1>();
}
std::unique_ptr<AbstractProductB> createProductB() override {
return std::make_unique<ProductB1>();
}
};
调用方式
cpp
复制代码
auto factory = std::make_unique<ConcreteFactory1>();
auto pA = factory->createProductA();
auto pB = factory->createProductB();
4. 建造者模式(Builder)
关键点
- 将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同表示。
- 适用于对象由多个部分组成、且构造过程复杂。
- c++中不可变对象推荐使用 "命名构造器" 或 "参数对象",而不是 Builder 模式,防止过度设计。
优缺点
| 优点 |
缺点 |
| 分离构造与表示 |
代码量大 |
| 可精细控制构建过程 |
仅适用于复杂对象 |
C++ 实现(现代 C++ 风格,使用 fluent interface)
cpp
复制代码
class Product {
public:
void setPartA(int a) { partA_ = a; }
void setPartB(std::string b) { partB_ = std::move(b); }
private:
int partA_ = 0;
std::string partB_;
};
class Builder {
public:
virtual ~Builder() = default;
virtual Builder& setPartA(int a) = 0;
virtual Builder& setPartB(std::string b) = 0;
virtual Product build() = 0;
};
class ConcreteBuilder : public Builder {
Product product_;
public:
Builder& setPartA(int a) override {
product_.setPartA(a);
return *this;
}
Builder& setPartB(std::string b) override {
product_.setPartB(std::move(b));
return *this;
}
Product build() override {
return std::move(product_);
}
};
调用方式(链式调用)
cpp
复制代码
ConcreteBuilder builder;
auto product = builder.setPartA(10).setPartB("hello").build();
5. 原型模式(Prototype)
关键点
- 通过复制现有对象(原型)来创建新对象,而非通过 new。
- 要求对象支持克隆(深拷贝)。
优缺点
| 优点 |
缺点 |
| 避免重复初始化开销 |
需要正确实现深拷贝 |
| 动态配置对象 |
循环引用等复杂结构难克隆 |
C++ 实现(使用 clone 虚函数)
cpp
复制代码
class Prototype {
public:
virtual ~Prototype() = default;
virtual std::unique_ptr<Prototype> clone() const = 0;
};
class ConcretePrototype : public Prototype {
int value_;
std::string data_;
public:
ConcretePrototype(int v, std::string d) : value_(v), data_(std::move(d)) {}
std::unique_ptr<Prototype> clone() const override {
return std::make_unique<ConcretePrototype>(*this); // 调用拷贝构造
}
};
调用方式
cpp
复制代码
ConcretePrototype proto(42, "example");
auto copy = proto.clone(); // 返回 unique_ptr<Prototype>