# C++设计模式:工厂模式(Factory Pattern) 工厂模式是最重要的创建型设计模式之一,它通过封装对象创建过程,实现了创建与使用的解耦。 工厂模式的三种变体:简单工厂模式、工厂方法模式和抽象工厂模式,以及它们在 C++中的现代实现方式。 ------ ## 🎯 写在前面 你是否遇到过这样的问题: - • 🎨 **图形系统**:需要根据用户选择创建不同类型的图形(圆形、矩形、三角形),但不想在业务代码中直接使用`new Circle()`、`new Rectangle()` - • 🗄️ **数据库连接**:需要根据配置创建不同类型的数据库连接(MySQL、PostgreSQL、SQLite),但希望代码与具体数据库类型解耦 - • 🎮 **游戏开发**:需要根据关卡类型创建不同的敌人(普通敌人、Boss、精英怪),但希望添加新敌人类型时不影响现有代码 - • 📦 **序列化系统**:需要根据文件格式创建不同的序列化器(JSON、XML、Binary),但希望统一接口 传统方法的问题: ``` // ❌ 问题1:业务代码与具体类耦合 void drawShape(const std::string& type) { if (type == "circle") { Circle* circle = new Circle(); // 直接依赖具体类 circle->draw(); delete circle; } else if (type == "rectangle") { Rectangle* rect = new Rectangle(); // 需要知道所有具体类 rect->draw(); delete rect; } // 添加新类型需要修改这里 } // ❌ 问题2:创建逻辑分散,难以维护 // 问题3:违反开闭原则(对扩展开放,对修改关闭) ``` **工厂模式**就是为了解决这些问题而生的!它封装了对象创建过程,实现了创建与使用的解耦。 ------ ## 🧠 工厂模式核心概念 ### 什么是工厂模式? **工厂模式(Factory Pattern)**是一种创建型设计模式,它提供了一种创建对象的最佳方式。工厂模式的核心思想是:**将对象的创建过程封装起来,让使用者不需要知道对象的具体创建细节**。 ### 工厂模式的三种变体 工厂模式有三种主要变体,它们解决的问题和复杂度不同: 1. 1. **简单工厂模式(Simple Factory)**:一个工厂类根据参数创建不同类型的对象 2. 2. **工厂方法模式(Factory Method)**:每个产品都有对应的工厂类 3. 3. **抽象工厂模式(Abstract Factory)**:创建一系列相关或依赖的对象族 ### 工厂模式的 UML 图 **简单工厂模式**: ``` ┌──────────────┐ │ Product │ │ (接口/基类) │ └──────┬───────┘ │ ┌───┴────┐ │ │ ┌──▼──┐ ┌─▼────┐ │Circle│ │Rect │ └──────┘ └─────┘ ┌──────────────┐ │ SimpleFactory│ ├──────────────┤ │+create() │ └──────────────┘ ``` **工厂方法模式**: ``` ┌──────────────┐ ┌──────────────┐ │ Product │ │ Factory │ │ (接口/基类) │ │ (接口/基类) │ └──────┬───────┘ └──────┬───────┘ │ │ ┌───┴────┐ ┌─────┴─────┐ │ │ │ │ ┌──▼──┐ ┌─▼────┐ ┌──▼──┐ ┌─────▼──┐ │Circle│ │Rect │ │Circle│ │Rect │ │ │ │ │ │Factory│ │Factory│ └──────┘ └─────┘ └──────┘ └───────┘ ``` ------ ## 💻 简单工厂模式(Simple Factory) ### 模式介绍 **简单工厂模式**是最基础的工厂模式,它通过一个工厂类根据传入的参数决定创建哪种产品对象。 ### 实现代码 ``` #include #include #include // 产品基类 class Shape { public: virtual ~Shape() = default; virtual void draw() = 0; }; // 具体产品:圆形 class Circle : public Shape { public: void draw() override { std::cout << "绘制圆形\n"; } }; // 具体产品:矩形 class Rectangle : public Shape { public: void draw() override { std::cout << "绘制矩形\n"; } }; // 具体产品:三角形 class Triangle : public Shape { public: void draw() override { std::cout << "绘制三角形\n"; } }; // 简单工厂类 class ShapeFactory { public: // 根据类型创建对象 static std::unique_ptr createShape(const std::string& type) { if (type == "circle") { return std::make_unique(); } else if (type == "rectangle") { return std::make_unique(); } else if (type == "triangle") { return std::make_unique(); } else { throw std::invalid_argument("未知的图形类型: " + type); } } }; // 使用示例 int main() { try { // 通过工厂创建对象,不需要知道具体类 auto circle = ShapeFactory::createShape("circle"); circle->draw(); auto rect = ShapeFactory::createShape("rectangle"); rect->draw(); auto triangle = ShapeFactory::createShape("triangle"); triangle->draw(); } catch (const std::exception& e) { std::cerr << "错误: " << e.what() << std::endl; } return 0; } ``` ### 优点 - • ✅ 客户端与具体产品类解耦 - • ✅ 集中管理对象创建逻辑 - • ✅ 代码简单易懂 ### 缺点 - • ❌ 违反开闭原则:添加新产品需要修改工厂类 - • ❌ 工厂类职责过重,包含所有创建逻辑 - • ❌ 难以扩展 ------ ## 🏭 工厂方法模式(Factory Method) ### 模式介绍 **工厂方法模式**为每个产品提供一个对应的工厂类,这样添加新产品时只需要添加新的工厂类,不需要修改现有代码。 ### 实现代码 ``` #include #include #include // 产品基类 class Shape { public: virtual ~Shape() = default; virtual void draw() = 0; }; // 具体产品 class Circle : public Shape { public: void draw() override { std::cout << "绘制圆形\n"; } }; class Rectangle : public Shape { public: void draw() override { std::cout << "绘制矩形\n"; } }; // 工厂基类 class ShapeFactory { public: virtual ~ShapeFactory() = default; virtual std::unique_ptr createShape() = 0; }; // 具体工厂:圆形工厂 class CircleFactory : public ShapeFactory { public: std::unique_ptr createShape() override { return std::make_unique(); } }; // 具体工厂:矩形工厂 class RectangleFactory : public ShapeFactory { public: std::unique_ptr createShape() override { return std::make_unique(); } }; // 使用示例 void renderShape(ShapeFactory& factory) { auto shape = factory.createShape(); shape->draw(); } int main() { CircleFactory circleFactory; RectangleFactory rectFactory; renderShape(circleFactory); renderShape(rectFactory); return 0; } ``` ### 优点 - • ✅ 符合开闭原则:添加新产品只需添加新工厂类 - • ✅ 每个工厂职责单一 - • ✅ 易于扩展和维护 ### 缺点 - • ⚠️ 类的数量增加(每个产品对应一个工厂) - • ⚠️ 增加了系统复杂度 ------ ## 🏢 抽象工厂模式(Abstract Factory) ### 模式介绍 **抽象工厂模式**提供一个接口,用于创建一系列相关或依赖的对象,而不需要指定它们的具体类。它适用于需要创建产品族(多个相关产品)的场景。 ### 实现代码 ``` #include #include #include // 抽象产品A:按钮 class Button { public: virtual ~Button() = default; virtual void render() = 0; }; // 抽象产品B:窗口 class Window { public: virtual ~Window() = default; virtual void render() = 0; }; // Windows风格的具体产品 class WindowsButton : public Button { public: void render() override { std::cout << "渲染Windows风格按钮\n"; } }; class WindowsWindow : public Window { public: void render() override { std::cout << "渲染Windows风格窗口\n"; } }; // Linux风格的具体产品 class LinuxButton : public Button { public: void render() override { std::cout << "渲染Linux风格按钮\n"; } }; class LinuxWindow : public Window { public: void render() override { std::cout << "渲染Linux风格窗口\n"; } }; // 抽象工厂 class UIFactory { public: virtual ~UIFactory() = default; virtual std::unique_ptr