工厂模式
1. 简单工厂模式(Simple Factory)
核心思想
- 定义一个工厂类,根据输入参数创建不同的具体对象。
- 客户端不直接调用具体类的构造函数,而是通过工厂类获取对象。
示例代码
#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 Circleauto rect = ShapeFactory::createShape(ShapeFactory::Type::Rectangle);rect->draw(); // Output: Drawing a Rectanglereturn 0;
}
特点
- 优点:代码简单,集中管理对象的创建逻辑。
- 缺点:违反开闭原则(新增类型需修改工厂类)。
2. 工厂方法模式(Factory Method)
核心思想
- 定义一个创建对象的抽象接口,由子类决定具体实例化的类。
- 每个具体产品对应一个具体工厂类。
示例代码
#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 buttonMacOSButtonFactory macFactory;renderUI(macFactory); // Output: Rendering a MacOS-style buttonreturn 0;
}
特点
- 优点:符合开闭原则,扩展新类型只需添加新工厂类。
- 缺点:类数量增加,系统复杂度提升。
3. 抽象工厂模式(Abstract Factory)
核心思想
- 提供一个接口,用于创建一组相关或依赖的对象家族。
- 适合需要创建多个协同工作的对象的场景(如 GUI 组件库)。
示例代码
#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 TextBoxMacOSFactory macFactory;createUI(macFactory); // Output:// MacOS Button// MacOS TextBoxreturn 0;
}
特点
- 优点:保证产品家族的兼容性(如统一风格)。
- 缺点:扩展新产品家族需要修改所有工厂接口。
工厂模式的核心对比
模式 | 适用场景 | 扩展性 | 复杂度 |
---|---|---|---|
简单工厂 | 对象类型少且固定 | 违反开闭原则 | 低 |
工厂方法 | 单一产品,需灵活扩展具体类型 | 新增产品类型只需添加新工厂 | 中 |
抽象工厂 | 需要创建一组相关的对象(产品家族) | 新增产品家族需修改接口 | 高 |
工厂模式的典型应用场景
- 跨平台 UI 开发:为不同操作系统创建风格一致的组件。
- 游戏开发:动态生成不同类别的敌人或道具。
- 数据库访问:根据配置创建 MySQL/Oracle 连接对象。
- 插件系统:加载第三方模块时动态创建对象。
最佳实践
-
优先使用工厂方法模式:
在需要灵活扩展时,避免简单工厂的硬编码逻辑。 -
结合智能指针管理对象:
使用std::unique_ptr
或std::shared_ptr
自动释放资源。std::unique_ptr<Button> button = factory.createButton();
-
避免过度设计:
如果对象创建逻辑简单,直接使用构造函数可能更高效。
总结
工厂模式通过封装对象的创建过程,实现以下目标:
- 解耦:客户端代码与具体类解耦。
- 可维护性:集中管理创建逻辑,便于修改和扩展。
- 灵活性:支持动态切换产品类型或家族。