工厂模式总结

工厂模式


1. 简单工厂模式(Simple Factory)

核心思想
  • 定义一个工厂类,根据输入参数创建不同的具体对象。
  • 客户端不直接调用具体类的构造函数,而是通过工厂类获取对象。
示例代码
cpp 复制代码
#include <iostream>
#include <memory>

// 抽象产品类
class Shape {
public:
    virtual void draw() = 0;
    virtual ~Shape() = default;
};

// 具体产品类:圆形
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:
    enum class Type { Circle, Rectangle };

    // 创建对象的方法
    static std::unique_ptr<Shape> createShape(Type type) {
        switch (type) {
            case Type::Circle:
                return std::make_unique<Circle>();
            case Type::Rectangle:
                return std::make_unique<Rectangle>();
            default:
                throw std::invalid_argument("Invalid shape type");
        }
    }
};

// 客户端使用
int main() {
    auto circle = ShapeFactory::createShape(ShapeFactory::Type::Circle);
    circle->draw();  // Output: Drawing a Circle

    auto rect = ShapeFactory::createShape(ShapeFactory::Type::Rectangle);
    rect->draw();    // Output: Drawing a Rectangle

    return 0;
}
特点
  • 优点:代码简单,集中管理对象的创建逻辑。
  • 缺点:违反开闭原则(新增类型需修改工厂类)。

2. 工厂方法模式(Factory Method)

核心思想
  • 定义一个创建对象的抽象接口,由子类决定具体实例化的类。
  • 每个具体产品对应一个具体工厂类。
示例代码
cpp 复制代码
#include <iostream>
#include <memory>

// 抽象产品类
class Button {
public:
    virtual void render() = 0;
    virtual ~Button() = default;
};

// 具体产品类:Windows 按钮
class WindowsButton : public Button {
public:
    void render() override {
        std::cout << "Rendering a Windows-style button" << std::endl;
    }
};

// 具体产品类:MacOS 按钮
class MacOSButton : public Button {
public:
    void render() override {
        std::cout << "Rendering a MacOS-style button" << std::endl;
    }
};

// 抽象工厂类
class ButtonFactory {
public:
    virtual std::unique_ptr<Button> createButton() = 0;
    virtual ~ButtonFactory() = default;
};

// 具体工厂类:Windows 按钮工厂
class WindowsButtonFactory : public ButtonFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<WindowsButton>();
    }
};

// 具体工厂类:MacOS 按钮工厂
class MacOSButtonFactory : public ButtonFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<MacOSButton>();
    }
};

// 客户端使用
void renderUI(ButtonFactory& factory) {
    auto button = factory.createButton();
    button->render();
}

int main() {
    WindowsButtonFactory winFactory;
    renderUI(winFactory);  // Output: Rendering a Windows-style button

    MacOSButtonFactory macFactory;
    renderUI(macFactory);  // Output: Rendering a MacOS-style button

    return 0;
}
特点
  • 优点:符合开闭原则,扩展新类型只需添加新工厂类。
  • 缺点:类数量增加,系统复杂度提升。

3. 抽象工厂模式(Abstract Factory)

核心思想
  • 提供一个接口,用于创建一组相关或依赖的对象家族
  • 适合需要创建多个协同工作的对象的场景(如 GUI 组件库)。
示例代码
cpp 复制代码
#include <iostream>
#include <memory>

// 抽象产品类:按钮
class Button {
public:
    virtual void render() = 0;
    virtual ~Button() = default;
};

// 抽象产品类:文本框
class TextBox {
public:
    virtual void input() = 0;
    virtual ~TextBox() = default;
};

// Windows 系列产品
class WindowsButton : public Button {
public:
    void render() override {
        std::cout << "Windows Button" << std::endl;
    }
};

class WindowsTextBox : public TextBox {
public:
    void input() override {
        std::cout << "Windows TextBox" << std::endl;
    }
};

// MacOS 系列产品
class MacOSButton : public Button {
public:
    void render() override {
        std::cout << "MacOS Button" << std::endl;
    }
};

class MacOSTextBox : public TextBox {
public:
    void input() override {
        std::cout << "MacOS TextBox" << std::endl;
    }
};

// 抽象工厂接口
class GUIFactory {
public:
    virtual std::unique_ptr<Button> createButton() = 0;
    virtual std::unique_ptr<TextBox> createTextBox() = 0;
    virtual ~GUIFactory() = default;
};

// 具体工厂:Windows 工厂
class WindowsFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<WindowsButton>();
    }
    std::unique_ptr<TextBox> createTextBox() override {
        return std::make_unique<WindowsTextBox>();
    }
};

// 具体工厂:MacOS 工厂
class MacOSFactory : public GUIFactory {
public:
    std::unique_ptr<Button> createButton() override {
        return std::make_unique<MacOSButton>();
    }
    std::unique_ptr<TextBox> createTextBox() override {
        return std::make_unique<MacOSTextBox>();
    }
};

// 客户端使用
void createUI(GUIFactory& factory) {
    auto button = factory.createButton();
    auto textBox = factory.createTextBox();
    button->render();
    textBox->input();
}

int main() {
    WindowsFactory winFactory;
    createUI(winFactory);  
    // Output: 
    // Windows Button
    // Windows TextBox

    MacOSFactory macFactory;
    createUI(macFactory);  
    // Output:
    // MacOS Button
    // MacOS TextBox

    return 0;
}
特点
  • 优点:保证产品家族的兼容性(如统一风格)。
  • 缺点:扩展新产品家族需要修改所有工厂接口。

工厂模式的核心对比

模式 适用场景 扩展性 复杂度
简单工厂 对象类型少且固定 违反开闭原则
工厂方法 单一产品,需灵活扩展具体类型 新增产品类型只需添加新工厂
抽象工厂 需要创建一组相关的对象(产品家族) 新增产品家族需修改接口

工厂模式的典型应用场景

  1. 跨平台 UI 开发:为不同操作系统创建风格一致的组件。
  2. 游戏开发:动态生成不同类别的敌人或道具。
  3. 数据库访问:根据配置创建 MySQL/Oracle 连接对象。
  4. 插件系统:加载第三方模块时动态创建对象。

最佳实践

  1. 优先使用工厂方法模式

    在需要灵活扩展时,避免简单工厂的硬编码逻辑。

  2. 结合智能指针管理对象

    使用 std::unique_ptrstd::shared_ptr 自动释放资源。

    c++ 复制代码
    std::unique_ptr<Button> button = factory.createButton();
  3. 避免过度设计

    如果对象创建逻辑简单,直接使用构造函数可能更高效。


总结

工厂模式通过封装对象的创建过程,实现以下目标:

  • 解耦:客户端代码与具体类解耦。
  • 可维护性:集中管理创建逻辑,便于修改和扩展。
  • 灵活性:支持动态切换产品类型或家族。