Abstract Factory(抽象工厂)模式是一种创建型设计模式,用于生产一系列相关或依赖的对象,而无需指定它们的具体类。它通过抽象接口定义产品族,由具体工厂实现这些接口来生成不同系列的产品。
1. Abstract Factory 模式详解
核心角色
-
AbstractFactory(抽象工厂)
-
声明创建一组产品的接口(如
CreateProductA
,CreateProductB
)。
-
-
ConcreteFactory(具体工厂)
-
实现抽象工厂接口,生成同一产品族的具体对象(如
ConcreteFactory1
生成ProductA1
和ProductB1
)。
-
-
AbstractProduct(抽象产品)
-
定义产品的接口(如
IAbstractProductA
,IAbstractProductB
)。
-
-
ConcreteProduct(具体产品)
-
实现抽象产品接口的具体类。
-
适用场景
-
需要创建多个相关联的产品(如跨平台的 UI 组件:按钮 + 文本框)。
-
系统需要独立于产品的创建过程(如切换数据库:MySQL → Oracle)。
2. C++ 实现示例
假设生产两种产品族:
-
家具工厂(现代风格 vs. 古典风格)
-
产品:
Chair
(椅子) +Sofa
(沙发)
-
#include <iostream>
#include <string>
// ------ 抽象产品 ------
class Chair {
public:
virtual void sitOn() = 0;
};
class Sofa {
public:
virtual void lieOn() = 0;
};
// ------ 具体产品(现代风格) ------
class ModernChair : public Chair {
public:
void sitOn() override {
std::cout << "Sitting on a modern chair." << std::endl;
}
};
class ModernSofa : public Sofa {
public:
void lieOn() override {
std::cout << "Lying on a modern sofa." << std::endl;
}
};
// ------ 具体产品(古典风格) ------
class ClassicChair : public Chair {
public:
void sitOn() override {
std::cout << "Sitting on a classic chair." << std::endl;
}
};
class ClassicSofa : public Sofa {
public:
void lieOn() override {
std::cout << "Lying on a classic sofa." << std::endl;
}
};
// ------ 抽象工厂 ------
class FurnitureFactory {
public:
virtual Chair* createChair() = 0;
virtual Sofa* createSofa() = 0;
};
// ------ 具体工厂(现代风格) ------
class ModernFurnitureFactory : public FurnitureFactory {
public:
Chair* createChair() override {
return new ModernChair();
}
Sofa* createSofa() override {
return new ModernSofa();
}
};
// ------ 具体工厂(古典风格) ------
class ClassicFurnitureFactory : public FurnitureFactory {
public:
Chair* createChair() override {
return new ClassicChair();
}
Sofa* createSofa() override {
return new ClassicSofa();
}
};
// ------ 客户端代码 ------
int main() {
// 选择现代风格工厂
FurnitureFactory* factory = new ModernFurnitureFactory();
Chair* chair = factory->createChair();
Sofa* sofa = factory->createSofa();
chair->sitOn(); // Output: Sitting on a modern chair.
sofa->lieOn(); // Output: Lying on a modern sofa.
delete factory;
delete chair;
delete sofa;
return 0;
}
3. C# 实现示例
假设生产两种 UI 组件(Windows vs. Mac):
按钮(Button) + 复选框(Checkbox)
using System;
// ------ 抽象产品 ------
interface IButton {
void Render();
}
interface ICheckbox {
void Toggle();
}
// ------ 具体产品(Windows 风格) ------
class WindowsButton : IButton {
public void Render() {
Console.WriteLine("Rendering a Windows-style button.");
}
}
class WindowsCheckbox : ICheckbox {
public void Toggle() {
Console.WriteLine("Toggling a Windows-style checkbox.");
}
}
// ------ 具体产品(Mac 风格) ------
class MacButton : IButton {
public void Render() {
Console.WriteLine("Rendering a Mac-style button.");
}
}
class MacCheckbox : ICheckbox {
public void Toggle() {
Console.WriteLine("Toggling a Mac-style checkbox.");
}
}
// ------ 抽象工厂 ------
interface IGUIFactory {
IButton CreateButton();
ICheckbox CreateCheckbox();
}
// ------ 具体工厂(Windows 风格) ------
class WindowsFactory : IGUIFactory {
public IButton CreateButton() {
return new WindowsButton();
}
public ICheckbox CreateCheckbox() {
return new WindowsCheckbox();
}
}
// ------ 具体工厂(Mac 风格) ------
class MacFactory : IGUIFactory {
public IButton CreateButton() {
return new MacButton();
}
public ICheckbox CreateCheckbox() {
return new MacCheckbox();
}
}
// ------ 客户端代码 ------
class Program {
static void Main(string[] args) {
// 选择 Mac 风格工厂
IGUIFactory factory = new MacFactory();
IButton button = factory.CreateButton();
ICheckbox checkbox = factory.CreateCheckbox();
button.Render(); // Output: Rendering a Mac-style button.
checkbox.Toggle(); // Output: Toggling a Mac-style checkbox.
}
}
4. 模式总结
优点 缺点
✅ 保证产品族的兼容性(如所有组件风格一致) ❌ 新增产品类型需修改所有工厂类
✅ 客户端代码与具体类解耦 ❌ 代码复杂度较高
适用场景:
跨平台 UI 组件(Windows/Mac/Linux)。
数据库访问层(MySQL/Oracle/SQL Server)。
游戏引擎(不同渲染风格的角色/场景)。