跳转到内容

C++ 工厂方法模式

来自代码酷

C++工厂方法模式[编辑 | 编辑源代码]

工厂方法模式(Factory Method Pattern)是面向对象编程中常用的设计模式之一,属于创建型模式。它提供了一种将对象的实例化过程延迟到子类的方法,从而使得子类可以决定实例化哪个类。工厂方法模式的核心思想是定义一个创建对象的接口,但由子类决定具体实例化的类。

介绍[编辑 | 编辑源代码]

工厂方法模式通过将对象的创建过程封装在工厂类中,使得客户端代码无需关心具体的实现细节,从而降低耦合度。该模式适用于以下场景:

  • 一个类无法预知它需要创建哪种对象。
  • 一个类希望由它的子类来指定所创建的对象。
  • 系统需要动态选择对象的创建方式。

模式结构[编辑 | 编辑源代码]

工厂方法模式包含以下主要角色:

  • 抽象产品(Product):定义产品的接口。
  • 具体产品(ConcreteProduct):实现抽象产品的具体类。
  • 抽象工厂(Creator):声明工厂方法,返回一个产品对象。
  • 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品的实例。

classDiagram class Product { <<interface>> +operation() } class ConcreteProductA { +operation() } class ConcreteProductB { +operation() } class Creator { <<abstract>> +factoryMethod()* Product +someOperation() } class ConcreteCreatorA { +factoryMethod() Product } class ConcreteCreatorB { +factoryMethod() Product } Product <|-- ConcreteProductA Product <|-- ConcreteProductB Creator <|-- ConcreteCreatorA Creator <|-- ConcreteCreatorB Creator ..> Product : creates

代码示例[编辑 | 编辑源代码]

以下是一个简单的C++实现示例,展示如何使用工厂方法模式创建不同类型的对象。

#include <iostream>
#include <memory>

// 抽象产品
class Product {
public:
    virtual ~Product() = default;
    virtual void operation() const = 0;
};

// 具体产品A
class ConcreteProductA : public Product {
public:
    void operation() const override {
        std::cout << "ConcreteProductA operation called." << std::endl;
    }
};

// 具体产品B
class ConcreteProductB : public Product {
public:
    void operation() const override {
        std::cout << "ConcreteProductB operation called." << std::endl;
    }
};

// 抽象工厂
class Creator {
public:
    virtual ~Creator() = default;
    virtual std::unique_ptr<Product> factoryMethod() const = 0;

    void someOperation() const {
        std::unique_ptr<Product> product = factoryMethod();
        product->operation();
    }
};

// 具体工厂A
class ConcreteCreatorA : public Creator {
public:
    std::unique_ptr<Product> factoryMethod() const override {
        return std::make_unique<ConcreteProductA>();
    }
};

// 具体工厂B
class ConcreteCreatorB : public Creator {
public:
    std::unique_ptr<Product> factoryMethod() const override {
        return std::make_unique<ConcreteProductB>();
    }
};

// 客户端代码
int main() {
    std::unique_ptr<Creator> creatorA = std::make_unique<ConcreteCreatorA>();
    creatorA->someOperation();  // 输出: ConcreteProductA operation called.

    std::unique_ptr<Creator> creatorB = std::make_unique<ConcreteCreatorB>();
    creatorB->someOperation();  // 输出: ConcreteProductB operation called.

    return 0;
}

代码解释[编辑 | 编辑源代码]

1. Product 是抽象基类,定义了产品的接口。 2. ConcreteProductAConcreteProductB 是具体产品类,实现了抽象产品的接口。 3. Creator 是抽象工厂类,声明了工厂方法 `factoryMethod()`。 4. ConcreteCreatorAConcreteCreatorB 是具体工厂类,实现了 `factoryMethod()`,分别返回不同的产品实例。 5. 客户端代码通过调用具体工厂的 `someOperation()` 方法,间接调用了工厂方法创建产品对象。

实际应用场景[编辑 | 编辑源代码]

工厂方法模式在以下场景中非常有用:

  • **GUI框架**:不同的操作系统(如Windows、macOS)需要创建不同的按钮或窗口对象。
  • **游戏开发**:不同类型的敌人或道具可以通过工厂方法动态创建。
  • **数据库连接**:不同的数据库(MySQL、PostgreSQL)需要不同的连接对象。

案例:跨平台UI组件[编辑 | 编辑源代码]

假设我们正在开发一个跨平台的UI库,需要在Windows和Linux上创建不同的按钮组件:

#include <iostream>
#include <memory>

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

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

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

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

    void renderDialog() const {
        std::unique_ptr<Button> button = createButton();
        button->render();
    }
};

// 具体工厂:Windows对话框
class WindowsDialog : public Dialog {
public:
    std::unique_ptr<Button> createButton() const override {
        return std::make_unique<WindowsButton>();
    }
};

// 具体工厂:Linux对话框
class LinuxDialog : public Dialog {
public:
    std::unique_ptr<Button> createButton() const override {
        return std::make_unique<LinuxButton>();
    }
};

int main() {
    std::unique_ptr<Dialog> windowsDialog = std::make_unique<WindowsDialog>();
    windowsDialog->renderDialog();  // 输出: Rendering a Windows-style button.

    std::unique_ptr<Dialog> linuxDialog = std::make_unique<LinuxDialog>();
    linuxDialog->renderDialog();    // 输出: Rendering a Linux-style button.

    return 0;
}

工厂方法模式 vs 简单工厂模式[编辑 | 编辑源代码]

工厂方法模式与简单工厂模式的主要区别在于:

  • 简单工厂模式:由一个工厂类负责所有产品的创建,不符合开闭原则(对扩展开放,对修改封闭)。
  • 工厂方法模式:将工厂的创建逻辑分散到子类中,符合开闭原则,但增加了类的数量。

数学表示[编辑 | 编辑源代码]

工厂方法模式可以形式化表示为: {ProductConcreteProductAProductConcreteProductBCreatorConcreteCreatorACreatorConcreteCreatorBCreator×Productoperation()

总结[编辑 | 编辑源代码]

工厂方法模式通过将对象的创建过程委托给子类,实现了对象的动态创建,提高了代码的灵活性和可扩展性。它适用于需要动态选择对象类型的场景,同时符合面向对象设计原则中的依赖倒置原则开闭原则