C++ 工厂方法模式
外观
C++工厂方法模式[编辑 | 编辑源代码]
工厂方法模式(Factory Method Pattern)是面向对象编程中常用的设计模式之一,属于创建型模式。它提供了一种将对象的实例化过程延迟到子类的方法,从而使得子类可以决定实例化哪个类。工厂方法模式的核心思想是定义一个创建对象的接口,但由子类决定具体实例化的类。
介绍[编辑 | 编辑源代码]
工厂方法模式通过将对象的创建过程封装在工厂类中,使得客户端代码无需关心具体的实现细节,从而降低耦合度。该模式适用于以下场景:
- 一个类无法预知它需要创建哪种对象。
- 一个类希望由它的子类来指定所创建的对象。
- 系统需要动态选择对象的创建方式。
模式结构[编辑 | 编辑源代码]
工厂方法模式包含以下主要角色:
- 抽象产品(Product):定义产品的接口。
- 具体产品(ConcreteProduct):实现抽象产品的具体类。
- 抽象工厂(Creator):声明工厂方法,返回一个产品对象。
- 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品的实例。
代码示例[编辑 | 编辑源代码]
以下是一个简单的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. ConcreteProductA 和 ConcreteProductB 是具体产品类,实现了抽象产品的接口。 3. Creator 是抽象工厂类,声明了工厂方法 `factoryMethod()`。 4. ConcreteCreatorA 和 ConcreteCreatorB 是具体工厂类,实现了 `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 简单工厂模式[编辑 | 编辑源代码]
工厂方法模式与简单工厂模式的主要区别在于:
- 简单工厂模式:由一个工厂类负责所有产品的创建,不符合开闭原则(对扩展开放,对修改封闭)。
- 工厂方法模式:将工厂的创建逻辑分散到子类中,符合开闭原则,但增加了类的数量。
数学表示[编辑 | 编辑源代码]
工厂方法模式可以形式化表示为:
总结[编辑 | 编辑源代码]
工厂方法模式通过将对象的创建过程委托给子类,实现了对象的动态创建,提高了代码的灵活性和可扩展性。它适用于需要动态选择对象类型的场景,同时符合面向对象设计原则中的依赖倒置原则和开闭原则。