抽象工厂模式 (Abstract Factory) 详解
背景与核心概念
抽象工厂模式是一种创建型设计模式,诞生于软件工程中对对象创建灵活性和系统可维护性的需求。该模式最早在1994年的《设计模式:可复用面向对象软件的基础》一书中被正式提出,是工厂方法模式的进一步抽象。
发展脉络
- 简单工厂阶段:最初通过一个工厂类根据参数创建不同对象
- 工厂方法阶段:为每种产品定义一个工厂接口,解决简单工厂的扩展性问题
- 抽象工厂阶段:进一步抽象,创建产品家族而非单个产品
关键术语
- 抽象工厂 (Abstract Factory):声明创建抽象产品对象的接口
- 具体工厂 (Concrete Factory):实现抽象工厂接口,创建具体产品对象
- 抽象产品 (Abstract Product):声明产品对象的接口
- 具体产品 (Concrete Product):实现抽象产品接口,定义具体产品
- 产品族 (Product Family):一组相关或依赖的产品对象
设计意图与考量
核心目标
- 封装创建逻辑:将对象创建过程封装在工厂中,客户端无需关心具体实现
- 解耦客户端与具体类:客户端只与抽象接口交互,降低系统耦合度
- 支持产品族一致性:确保创建的产品相互兼容,属于同一产品族
- 便于产品族切换:通过更换具体工厂,可以轻松切换整个产品族
设计考量
考量因素 | 说明 | 解决方案 |
---|---|---|
扩展性 | 新增产品族容易,新增产品种类困难 | 通过定义新的具体工厂支持新产品族 |
一致性 | 确保创建的产品相互兼容 | 同一工厂创建的产品属于同一产品族 |
复杂性 | 引入大量接口和类 | 权衡模式带来的好处与增加的复杂度 |
开闭原则 | 对扩展开放,对修改关闭 | 新增产品族无需修改现有代码 |
实例与应用场景
示例1:跨平台GUI组件库
// 抽象产品:按钮
class Button {
public:
virtual void render() = 0;
virtual void onClick() = 0;
virtual ~Button() {}
};
// 抽象产品:文本框
class TextBox {
public:
virtual void render() = 0;
virtual void onInput() = 0;
virtual ~TextBox() {}
};
// 具体产品:Windows按钮
class WindowsButton : public Button {
public:
void render() override {
std::cout << "渲染Windows风格按钮" << std::endl;
}
void onClick() override {
std::cout << "Windows按钮点击事件处理" << std::endl;
}
};
// 具体产品:Windows文本框
class WindowsTextBox : public TextBox {
public:
void render() override {
std::cout << "渲染Windows风格文本框" << std::endl;
}
void onInput() override {
std::cout << "Windows文本框输入事件处理" << std::endl;
}
};
// 具体产品:Mac按钮
class MacButton : public Button {
public:
void render() override {
std::cout << "渲染Mac风格按钮" << std::endl;
}
void onClick() override {
std::cout << "Mac按钮点击事件处理" << std::endl;
}
};
// 具体产品:Mac文本框
class MacTextBox : public TextBox {
public:
void render() override {
std::cout << "渲染Mac风格文本框" << std::endl;
}
void onInput() override {
std::cout << "Mac文本框输入事件处理" << std::endl;
}
};
// 抽象工厂
class GUIFactory {
public:
virtual Button* createButton() = 0;
virtual TextBox* createTextBox() = 0;
virtual ~GUIFactory() {}
};
// 具体工厂:Windows工厂
class WindowsFactory : public GUIFactory {
public:
Button* createButton() override {
return new WindowsButton();
}
TextBox* createTextBox() override {
return new WindowsTextBox();
}
};
// 具体工厂:Mac工厂
class MacFactory : public GUIFactory {
public:
Button* createButton() override {
return new MacButton();
}
TextBox* createTextBox() override {
return new MacTextBox();
}
};
// 客户端代码
class Application {
private:
GUIFactory* factory;
Button* button;
TextBox* textBox;
public:
Application(GUIFactory* factory) : factory(factory), button(nullptr), textBox(nullptr) {}
void createUI() {
button = factory->createButton();
textBox = factory->createTextBox();
}
void render() {
if (button) button->render();
if (textBox) textBox->render();
}
~Application() {
delete button;
delete textBox;
delete factory;
}
};
// 使用示例
int main() {
// 根据当前操作系统选择工厂
GUIFactory* factory;
#ifdef _WIN32
factory = new WindowsFactory();
#elif __APPLE__
factory = new MacFactory();
#endif
Application app(factory);
app.createUI();
app.render();
return 0;
}
示例2:数据库访问抽象工厂
// 抽象产品:数据库连接
class DatabaseConnection {
public:
virtual void connect() = 0;
virtual void disconnect() = 0;
virtual void executeQuery(const std::string& query) = 0;
virtual ~DatabaseConnection() {}
};
// 抽象产品:数据库命令
class DatabaseCommand {
public:
virtual void setConnection(DatabaseConnection* connection) = 0;
virtual void execute() = 0;
virtual ~DatabaseCommand() {}
};
// 具体产品:MySQL连接
class MySQLConnection : public DatabaseConnection {
public:
void connect() override {
std::cout << "连接到MySQL数据库" << std::endl;
}
void disconnect() override {
std::cout << "断开MySQL数据库连接" << std::endl;
}
void executeQuery(const std::string& query) override {
std::cout << "执行MySQL查询: " << query << std::endl;
}
};
// 具体产品:MySQL命令
class MySQLCommand : public DatabaseCommand {
private:
DatabaseConnection* connection;
public:
void setConnection(DatabaseConnection* conn) override {
connection = conn;
}
void execute() override {
if (connection) {
std::cout << "执行MySQL命令" << std::endl;
connection->executeQuery("SELECT * FROM users");
}
}
};
// 具体产品:PostgreSQL连接
class PostgreSQLConnection : public DatabaseConnection {
public:
void connect() override {
std::cout << "连接到PostgreSQL数据库" << std::endl;
}
void disconnect() override {
std::cout << "断开PostgreSQL数据库连接" << std::endl;
}
void executeQuery(const std::string& query) override {
std::cout << "执行PostgreSQL查询: " << query << std::endl;
}
};
// 具体产品:PostgreSQL命令
class PostgreSQLCommand : public DatabaseCommand {
private:
DatabaseConnection* connection;
public:
void setConnection(DatabaseConnection* conn) override {
connection = conn;
}
void execute() override {
if (connection) {
std::cout << "执行PostgreSQL命令" << std::endl;
connection->executeQuery("SELECT * FROM users");
}
}
};
// 抽象工厂
class DatabaseFactory {
public:
virtual DatabaseConnection* createConnection() = 0;
virtual DatabaseCommand* createCommand() = 0;
virtual ~DatabaseFactory() {}
};
// 具体工厂:MySQL工厂
class MySQLFactory : public DatabaseFactory {
public:
DatabaseConnection* createConnection() override {
return new MySQLConnection();
}
DatabaseCommand* createCommand() override {
return new MySQLCommand();
}
};
// 具体工厂:PostgreSQL工厂
class PostgreSQLFactory : public DatabaseFactory {
public:
DatabaseConnection* createConnection() override {
return new PostgreSQLConnection();
}
DatabaseCommand* createCommand() override {
return new PostgreSQLCommand();
}
};
// 客户端代码
class DatabaseClient {
private:
DatabaseFactory* factory;
DatabaseConnection* connection;
DatabaseCommand* command;
public:
DatabaseClient(DatabaseFactory* dbFactory)
: factory(dbFactory), connection(nullptr), command(nullptr) {}
void initialize() {
connection = factory->createConnection();
command = factory->createCommand();
connection->connect();
command->setConnection(connection);
}
void performOperation() {
if (command) {
command->execute();
}
}
~DatabaseClient() {
if (connection) {
connection->disconnect();
delete connection;
}
delete command;
delete factory;
}
};
// 使用示例
int main() {
// 根据配置选择数据库类型
std::string dbType = "MySQL"; // 可以从配置文件读取
DatabaseFactory* factory;
if (dbType == "MySQL") {
factory = new MySQLFactory();
} else if (dbType == "PostgreSQL") {
factory = new PostgreSQLFactory();
} else {
throw std::runtime_error("不支持的数据库类型");
}
DatabaseClient client(factory);
client.initialize();
client.performOperation();
return 0;
}
编译与运行
创建以下Makefile文件:
CXX = g++
CXXFLAGS = -std=c++11 -Wall
all: gui_example db_example
gui_example: gui_example.cpp
$(CXX) $(CXXFLAGS) -o gui_example gui_example.cpp
db_example: db_example.cpp
$(CXX) $(CXXFLAGS) -o db_example db_example.cpp
clean:
rm -f gui_example db_example
.PHONY: all clean
编译和运行:
# 编译
make
# 运行GUI示例
./gui_example
# 运行数据库示例
./db_example
交互性内容解析
抽象工厂模式的时序图
模式参与者交互说明
- 客户端 (Client):仅与抽象工厂和抽象产品接口交互
- 抽象工厂 (AbstractFactory):声明创建抽象产品的接口
- 具体工厂 (ConcreteFactory):实现抽象工厂接口,创建具体产品
- 抽象产品 (AbstractProduct):声明产品对象的接口
- 具体产品 (ConcreteProduct):实现抽象产品接口,定义具体产品
这种交互方式确保了客户端代码与具体产品类的实现解耦,提高了代码的灵活性和可维护性。
图示化呈现
抽象工厂模式类图
模式结构说明
- 抽象工厂:定义创建抽象产品对象的接口
- 具体工厂:实现抽象工厂接口,创建具体产品对象
- 抽象产品:为产品对象声明接口
- 具体产品:实现抽象产品接口,定义具体产品
这种结构确保了:
- 客户端与具体产品类解耦
- 产品族一致性(同一工厂创建的产品相互兼容)
- 易于切换产品族(只需更换具体工厂)
总结
抽象工厂模式是一种强大的创建型设计模式,特别适用于需要创建相关或依赖对象家族的场景。通过将对象创建过程抽象化,该模式实现了客户端代码与具体产品类的解耦,提高了系统的灵活性和可维护性。
模式优势
- 产品族一致性:确保创建的产品相互兼容
- 客户端与具体类解耦:客户端只与抽象接口交互
- 易于切换产品族:通过更换具体工厂即可切换整个产品族
- 符合开闭原则:新增产品族无需修改现有代码
适用场景
- 跨平台应用:为不同操作系统创建相应的UI组件
- 数据库访问:支持多种数据库系统,保持接口一致
- 主题系统:为应用程序提供可切换的视觉主题
- 游戏开发:为不同游戏风格创建相应的角色、道具等
注意事项
- 扩展产品种类困难:新增产品种类需要修改所有工厂类
- 增加了系统复杂度:引入了大量接口和类
- 理解难度较高:相对于简单工厂模式,抽象工厂模式更加复杂
在实际应用中,需要根据具体需求权衡是否使用抽象工厂模式。对于需要创建相关对象家族且需要保持产品一致性的场景,抽象工厂模式是一个优秀的选择。