經過前兩天的學習,我們已經掌握了單例模式與工廠方法模式,理解了如何控制實例個數與如何通過子類封裝對象的創建邏輯。
今天,我們將進一步深入“工廠”體系,學習抽象工廠模式(Abstract Factory Pattern),這是在實際項目中**用于創建“產品族”**的關鍵設計模式。
一、Day 1~2 回顧
? Day 1:單例模式
- 保證一個類只有一個實例。
- 適合日志系統、配置加載器、數據庫連接池等場景。
- 推薦使用 C++11 局部靜態變量實現線程安全。
? Day 2:工廠方法模式
- 將創建產品的職責下放給子類工廠。
- 滿足開閉原則:添加新產品時只需新增具體工廠和產品類。
- 適用于“產品種類多變”的系統結構。
二、抽象工廠模式簡介
📌 定義:
抽象工廠模式提供一個接口,用于創建一系列相關或相互依賴的對象,而無需指定它們具體的類。
關鍵詞:“一系列相關對象” → 產品族
? 場景關鍵詞:
- 多個產品類型(如按鈕、窗口)
- 同一系列產品(如 Windows 風格、Mac 風格)
- 產品之間存在匹配關系
三、類圖結構
+------------------------+| AbstractFactory ||------------------------|| +createButton() || +createCheckbox() |+-----------+------------+|+-----------------+-----------------+| |
+-------------+ +----------------+
| WinFactory | | MacFactory |
+-------------+ +----------------+
| +createButton() | | +createButton() |
| +createCheckbox() | | +createCheckbox()|產品結構(同理)
+-----------------+ +------------------+
| AbstractButton |<------| WinButton |
| | | MacButton |
+-----------------+ +------------------+
四、C++ 實現:跨平臺 UI 工廠
我們來設計一個跨平臺 GUI 庫,可以根據平臺生成不同風格的按鈕和復選框。
1. 抽象產品類
class Button {
public:virtual void paint() = 0;virtual ~Button() {}
};class Checkbox {
public:virtual void paint() = 0;virtual ~Checkbox() {}
};
2. 具體產品類
class WinButton : public Button {
public:void paint() override {std::cout << "繪制 Windows 風格按鈕" << std::endl;}
};class MacButton : public Button {
public:void paint() override {std::cout << "繪制 Mac 風格按鈕" << std::endl;}
};class WinCheckbox : public Checkbox {
public:void paint() override {std::cout << "繪制 Windows 風格復選框" << std::endl;}
};class MacCheckbox : public Checkbox {
public:void paint() override {std::cout << "繪制 Mac 風格復選框" << std::endl;}
};
3. 抽象工廠類
class GUIFactory {
public:virtual Button* createButton() = 0;virtual Checkbox* createCheckbox() = 0;virtual ~GUIFactory() {}
};
4. 具體工廠類
class WinFactory : public GUIFactory {
public:Button* createButton() override {return new WinButton();}Checkbox* createCheckbox() override {return new WinCheckbox();}
};class MacFactory : public GUIFactory {
public:Button* createButton() override {return new MacButton();}Checkbox* createCheckbox() override {return new MacCheckbox();}
};
5. 客戶端代碼
void render(GUIFactory* factory) {Button* btn = factory->createButton();Checkbox* chk = factory->createCheckbox();btn->paint();chk->paint();delete btn;delete chk;
}int main() {WinFactory win;MacFactory mac;render(&win);render(&mac);return 0;
}
五、優缺點分析
? 優點:
- 保證產品族之間的一致性(按鈕和復選框風格統一)
- 滿足開閉原則,支持新增平臺或產品族
- 客戶端代碼不依賴具體產品類,低耦合
? 缺點:
- 類數量增多,結構復雜
- 不方便支持新增“產品種類”(比如再加個菜單類)
六、今日練習題
?? 題目一:
設計一個跨平臺圖標與窗口組件的 UI 系統,要求使用抽象工廠模式構造 Icon
與 Window
兩類產品族,支持 Windows 與 Linux 兩個平臺。
?? 題目二:
抽象工廠模式和工廠方法模式的最大區別是什么?請簡潔說明并舉例。
七、小結與展望
抽象工廠模式適合管理“產品族”,比工廠方法更進一步封裝了對象創建的整體體系。掌握它有助于構建可擴展、可復用、風格一致的大型軟件系統。
明日預告:建造者模式(Builder Pattern) —— 用來構建“結構復雜對象”的強大模式,適合生成器、配置器類場景。