工廠模式
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();
-
避免過度設計:
如果對象創建邏輯簡單,直接使用構造函數可能更高效。
總結
工廠模式通過封裝對象的創建過程,實現以下目標:
- 解耦:客戶端代碼與具體類解耦。
- 可維護性:集中管理創建邏輯,便于修改和擴展。
- 靈活性:支持動態切換產品類型或家族。