抽象工厂模式 (Abstract Factory) 详解

背景与核心概念

抽象工厂模式是一种创建型设计模式,诞生于软件工程中对对象创建灵活性和系统可维护性的需求。该模式最早在1994年的《设计模式:可复用面向对象软件的基础》一书中被正式提出,是工厂方法模式的进一步抽象。

发展脉络

  1. 简单工厂阶段:最初通过一个工厂类根据参数创建不同对象
  2. 工厂方法阶段:为每种产品定义一个工厂接口,解决简单工厂的扩展性问题
  3. 抽象工厂阶段:进一步抽象,创建产品家族而非单个产品

关键术语

  • 抽象工厂 (Abstract Factory):声明创建抽象产品对象的接口
  • 具体工厂 (Concrete Factory):实现抽象工厂接口,创建具体产品对象
  • 抽象产品 (Abstract Product):声明产品对象的接口
  • 具体产品 (Concrete Product):实现抽象产品接口,定义具体产品
  • 产品族 (Product Family):一组相关或依赖的产品对象

设计意图与考量

核心目标

  1. 封装创建逻辑:将对象创建过程封装在工厂中,客户端无需关心具体实现
  2. 解耦客户端与具体类:客户端只与抽象接口交互,降低系统耦合度
  3. 支持产品族一致性:确保创建的产品相互兼容,属于同一产品族
  4. 便于产品族切换:通过更换具体工厂,可以轻松切换整个产品族

设计考量

考量因素说明解决方案
扩展性新增产品族容易,新增产品种类困难通过定义新的具体工厂支持新产品族
一致性确保创建的产品相互兼容同一工厂创建的产品属于同一产品族
复杂性引入大量接口和类权衡模式带来的好处与增加的复杂度
开闭原则对扩展开放,对修改关闭新增产品族无需修改现有代码

实例与应用场景

示例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

交互性内容解析

抽象工厂模式的时序图

ClientAbstractFactoryConcreteFactoryAbstractProductConcreteProductcreateProductA()new ProductA()return ProductAreturn ProductAcreateProductB()new ProductB()return ProductBreturn ProductBClientAbstractFactoryConcreteFactoryAbstractProductConcreteProduct

模式参与者交互说明

  1. 客户端 (Client):仅与抽象工厂和抽象产品接口交互
  2. 抽象工厂 (AbstractFactory):声明创建抽象产品的接口
  3. 具体工厂 (ConcreteFactory):实现抽象工厂接口,创建具体产品
  4. 抽象产品 (AbstractProduct):声明产品对象的接口
  5. 具体产品 (ConcreteProduct):实现抽象产品接口,定义具体产品

这种交互方式确保了客户端代码与具体产品类的实现解耦,提高了代码的灵活性和可维护性。

图示化呈现

抽象工厂模式类图

creates
creates
creates
creates
AbstractFactory
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory1
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
ConcreteFactory2
+createProductA() : AbstractProductA
+createProductB() : AbstractProductB
«interface»
AbstractProductA
+operationA()
«interface»
AbstractProductB
+operationB()
ProductA1
+operationA()
ProductA2
+operationA()
ProductB1
+operationB()
ProductB2
+operationB()

模式结构说明

  1. 抽象工厂:定义创建抽象产品对象的接口
  2. 具体工厂:实现抽象工厂接口,创建具体产品对象
  3. 抽象产品:为产品对象声明接口
  4. 具体产品:实现抽象产品接口,定义具体产品

这种结构确保了:

  • 客户端与具体产品类解耦
  • 产品族一致性(同一工厂创建的产品相互兼容)
  • 易于切换产品族(只需更换具体工厂)

总结

抽象工厂模式是一种强大的创建型设计模式,特别适用于需要创建相关或依赖对象家族的场景。通过将对象创建过程抽象化,该模式实现了客户端代码与具体产品类的解耦,提高了系统的灵活性和可维护性。

模式优势

  1. 产品族一致性:确保创建的产品相互兼容
  2. 客户端与具体类解耦:客户端只与抽象接口交互
  3. 易于切换产品族:通过更换具体工厂即可切换整个产品族
  4. 符合开闭原则:新增产品族无需修改现有代码

适用场景

  1. 跨平台应用:为不同操作系统创建相应的UI组件
  2. 数据库访问:支持多种数据库系统,保持接口一致
  3. 主题系统:为应用程序提供可切换的视觉主题
  4. 游戏开发:为不同游戏风格创建相应的角色、道具等

注意事项

  1. 扩展产品种类困难:新增产品种类需要修改所有工厂类
  2. 增加了系统复杂度:引入了大量接口和类
  3. 理解难度较高:相对于简单工厂模式,抽象工厂模式更加复杂

在实际应用中,需要根据具体需求权衡是否使用抽象工厂模式。对于需要创建相关对象家族且需要保持产品一致性的场景,抽象工厂模式是一个优秀的选择。

更多推荐