抽象工厂模式(Abstract Factory)------ 整套买,不散卖
大白话解释
你去宜家买家具,有两种风格:
- 北欧风套装
- 现代风套装
每一套都包含:
- 沙发(Sofa)
- 茶几(CoffeeTable)
👉 你只需要选风格 ,工厂自动给你整套家具,绝不混搭
抽象工厂模式:提供一个接口,用来创建一系列相关或相互依赖的对象,而不需要指定具体类。简单说就是------工厂的工厂,生产的是"一家子"产品。
常见场景:
- 跨平台 UI(Windows 主题 vs Mac 主题,按钮/滚动条/文本框风格要统一)
- 数据库访问层(MySQL 套件 vs PostgreSQL 套件)
- 游戏皮肤系统(沙漠主题 vs 雪地主题,所有元素风格统一)
和工厂方法的区别
| 工厂方法 | 抽象工厂 |
|---|---|
| 生产一种产品 | 生产一族产品(多种) |
| 一个工厂方法 | 多个工厂方法 |
| "给我造个日志器" | "给我造一整套 UI 组件" |
C++ 代码示例
场景:跨平台 UI 组件库,支持 Windows 风格和 Mac 风格。
cpp
#include <iostream>
#include <memory>
#include <string>
// ================================
// 抽象产品族:按钮、复选框
// ================================
class Button {
public:
virtual ~Button() = default;
virtual void render() = 0;
virtual void onClick() = 0;
};
class Checkbox {
public:
virtual ~Checkbox() = default;
virtual void render() = 0;
virtual void toggle() = 0;
};
// ================================
// Windows 风格产品
// ================================
class WindowsButton : public Button {
public:
void render() override {
std::cout << "[Windows] 渲染方形按钮,蓝色边框\n";
}
void onClick() override {
std::cout << "[Windows] 按钮点击:播放咔哒声\n";
}
};
class WindowsCheckbox : public Checkbox {
public:
void render() override {
std::cout << "[Windows] 渲染方形复选框\n";
}
void toggle() override {
std::cout << "[Windows] 复选框切换状态\n";
}
};
// ================================
// Mac 风格产品
// ================================
class MacButton : public Button {
public:
void render() override {
std::cout << "[Mac] 渲染圆角按钮,灰色渐变\n";
}
void onClick() override {
std::cout << "[Mac] 按钮点击:轻触反馈\n";
}
};
class MacCheckbox : public Checkbox {
public:
void render() override {
std::cout << "[Mac] 渲染圆形复选框\n";
}
void toggle() override {
std::cout << "[Mac] 复选框切换:流畅动画\n";
}
};
// ================================
// 抽象工厂接口
// ================================
class UIFactory {
public:
virtual ~UIFactory() = default;
virtual std::unique_ptr<Button> createButton() = 0;
virtual std::unique_ptr<Checkbox> createCheckbox() = 0;
};
// ================================
// 具体工厂:生产整套风格
// ================================
class WindowsUIFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<WindowsButton>();
}
std::unique_ptr<Checkbox> createCheckbox() override {
return std::make_unique<WindowsCheckbox>();
}
};
class MacUIFactory : public UIFactory {
public:
std::unique_ptr<Button> createButton() override {
return std::make_unique<MacButton>();
}
std::unique_ptr<Checkbox> createCheckbox() override {
return std::make_unique<MacCheckbox>();
}
};
// ================================
// 客户端:只依赖抽象,不关心具体实现
// ================================
class Application {
private:
std::unique_ptr<Button> button;
std::unique_ptr<Checkbox> checkbox;
public:
Application(UIFactory& factory) {
button = factory.createButton();
checkbox = factory.createCheckbox();
}
void buildUI() {
std::cout << "--- 构建界面 ---\n";
button->render();
checkbox->render();
}
void simulateInteraction() {
std::cout << "--- 模拟交互 ---\n";
button->onClick();
checkbox->toggle();
}
};
// ================================
// 根据环境选择工厂
// ================================
std::unique_ptr<UIFactory> createFactory(const std::string& os) {
if (os == "Windows") {
return std::make_unique<WindowsUIFactory>();
} else {
return std::make_unique<MacUIFactory>();
}
}
int main() {
std::cout << "======= Windows 应用 =======\n";
auto winFactory = createFactory("Windows");
Application winApp(*winFactory);
winApp.buildUI();
winApp.simulateInteraction();
std::cout << "\n======= Mac 应用 =======\n";
auto macFactory = createFactory("Mac");
Application macApp(*macFactory);
macApp.buildUI();
macApp.simulateInteraction();
return 0;
}
输出:
======= Windows 应用 =======
--- 构建界面 ---
[Windows] 渲染方形按钮,蓝色边框
[Windows] 渲染方形复选框
--- 模拟交互 ---
[Windows] 按钮点击:播放咔哒声
[Windows] 复选框切换状态
======= Mac 应用 =======
--- 构建界面 ---
[Mac] 渲染圆角按钮,灰色渐变
[Mac] 渲染圆形复选框
--- 模拟交互 ---
[Mac] 按钮点击:轻触反馈
[Mac] 复选框切换:流畅动画
优缺点
| 说明 | |
|---|---|
| ✅ 优点 | 保证产品族风格一致,不会"乱配" |
| ✅ 优点 | 切换产品族只需换一个工厂,代码改动极小 |
| ✅ 优点 | 符合开闭原则(新增产品族只加代码) |
| ❌ 缺点 | 新增产品种类(比如新增滚动条)需改所有工厂,麻烦 |
| ❌ 缺点 | 类的数量较多,结构复杂 |
一句话记忆
抽象工厂 = 宜家卖整套家具,北欧风工厂只产北欧货,现代风工厂只产现代货,绝不串货。