C++ 工厂模式
开闭原则
开闭原则是面向对象设计SOLID原则中的第二个原则,由Bertrand Meyer在1988年提出
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
核心思想是:
-
对扩展开放
- 允许在不修改现有代码的情况下,添加新的功能
- 通过继承、组合、接口等方式扩展行为
-
对修改关闭
- 现有代码应该保持稳定,不被频繁修改
- 修改现有代码可能引入新的错误
工厂模式
通过 ai 搜索可知:工厂模式是创建型设计模式的一种,它通过定义一个创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类。在C++中,工厂模式主要分为三种:简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory)。
简单工厂模式
简单工厂模式通过一个工厂类来决定创建哪种产品类的实例。用户只需要传递一个参数给工厂类,不需要关心创建细节,只需关心产品的接口。但是,每次增加一个产品时,都需要增加一个具体类和对象实现工厂,这会使得系统中类的个数成倍增加,增加了系统的复杂度。
实例代码如下
// 产品接口
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
// 具体产品
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Circle" << std::endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Rectangle" << std::endl;
}
};
// 简单工厂
class ShapeFactory {
public:
static std::unique_ptr<Shape> createShape(const std::string& type) {
if (type == "circle") {
return std::make_unique<Circle>();
} else if (type == "rectangle") {
return std::make_unique<Rectangle>();
}
return nullptr;
}
};
// 使用示例
int main() {
auto shape1 = ShapeFactory::createShape("circle");
auto shape2 = ShapeFactory::createShape("rectangle");
if (shape1) shape1->draw();
if (shape2) shape2->draw();
return 0;
}
Shape 为抽象产品类,通过虚函数定义产品的公共接口(
公共接口简单讲就是,通过抽象基类,所派生的产品类有相同的函数名,功能一致,但是函数实现的具体细节不完全一样
Circle 和 Rectangle 为派生出来的具体产品类,对 draw 函数有各自不一样的实现方式。为了通过参数,控制具体需要实现哪种产品类,我们可以定义简单工厂 ShapeFactory,通过 string 变量,选择需要实例化的产品类。
可以看到,抽象基类的指针也可以指向具体产品类,这样可以最大程度地节省代码改写量。
工厂方法
工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类的实例化推迟到子类中进行。这样的模式解决了简单工厂模式中的问题,即无法对修改关闭。
// 产品接口
class Shape {
public:
virtual void draw() = 0;
virtual ~Shape() {}
};
// 具体产品
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Circle" << std::endl;
}
};
class Rectangle : public Shape {
public:
void draw() override {
std::cout << "Drawing a Rectangle" << std::endl;
}
};
// 工厂方法
class ShapeFactory {
public:
virtual std::unique_ptr<Shape> createShape() = 0;
virtual ~ShapeFactory() = default; // 虚析构函数
};
class CircleFactory : public ShapeFactory{
public:
std::unique_ptr<Shape> createShape() override {
return std::make_unique<Circle>();
}
};
class RectangleFactory : public ShapeFactory{
public:
std::unique_ptr<Shape> createShape() override {
return std::make_unique<Rectangle>();
}
};
// 使用者
void drawFunc(ShapeFactory& factory){
auto shapeDraw = factory.createShape();
shapeDraw.draw();
};
int main(){
CircleFactory temp;
drawFunc(temp);
return 0;
}
工厂方法为每个具体产品创建了独立的工厂:CircleFactory,RectangleFactory,当添加了新的产品时,也需要添加对于产品的工厂。以下是简单工厂与工厂方法的特点分析:
// 简单工厂 - 一个类负责所有产品的创建
// LoggerFactory 需要知道所有Logger的创建细节
// 职责过多,随着产品增多会变得臃肿
// 工厂方法 - 每个工厂只负责一种产品的创建
// FileLoggerCreator 只关心 FileLogger 的创建
// ConsoleLoggerCreator 只关心 ConsoleLogger 的创建
// 职责清晰,符合单一职责原则
// 如果有20种产品:
// 简单工厂:1个工厂 + 20个产品 = 21个类
// 工厂方法:1个抽象工厂 + 20个具体工厂 + 20个产品 = 41个类
// 简单工厂减少了约50%的类数量
// 简单工厂:1个工厂类 + n个产品类
// 工厂方法:1个抽象工厂 + n个具体工厂 + n个产品类
// 工厂方法多了n个具体工厂类
适合简单工厂:
// 1. 产品种类少且固定
// 2. 不需要运行时动态扩展
// 3. 追求代码简洁性
// 4. 团队规模小,变更不频繁
适合工厂方法:
// 1. 产品类型可能频繁扩展
// 2. 不同产品需要不同的初始化逻辑
// 3. 框架设计,需要让子类决定创建什么
// 4. 需要支持多种配置的产品创建
抽象工厂模式
抽象工厂模式本质上是:
- 多个工厂方法模式的组合:每个
createXxx()方法都是一个工厂方法 - 更高层次的抽象:关注产品族而非单个产品
- 更强的约束保证:确保创建的所有产品都是兼容的
这种层次关系体现了面向对象设计的核心思想:从简单到复杂,通过组合构建更强大的抽象。
- 只有一个产品需要创建(工厂方法)
// 只关心创建按钮
class ButtonFactory {
public:
virtual Button* createButton() = 0;
};
- 需要创建多个相关产品(演变为抽象工厂)
// 需要创建一整套UI组件
class UIFactory {
public:
virtual Button* createButton() = 0;
virtual TextBox* createTextBox() = 0; // 新增需求
virtual CheckBox* createCheckBox() = 0; // 新增需求
};
参考资料
[1] deepseek.

最后更新于 2025年12月21日 --- 最初发表于 2025年12月21日
原创作者:LitBro
关于作者:c++ 让人秃头
本文链接: [https://www.cnblogs.com/LitBro/p/19380077]
版权声明:本文采用 BY-NC-SA协议,转载或引用请注明出处!
关于后续:碍于学业不精,如有描述不当,还请见谅并非常感谢指出

浙公网安备 33010602011771号