设计模式:工厂模式

        工厂模式(Factory Pattern)是C++中常用的设计模式之一,它属于创建型模式,提供了一种创建对象的最佳方式,而无需将对象创建的逻辑暴露给客户端。工厂模式的主要目的是定义一个用于创建对象的接口,但让子类决定实例化哪一个类。这样,工厂方法使一个类的实例化延迟到其子类。工厂模式可以进一步分为简单工厂模式工厂方法模式抽象工厂模式三种类型。

工厂模式的三种形式

1. 简单工厂模式(Simple Factory)

简单工厂模式并不是GoF定义的23种设计模式之一,但它是理解工厂模式的基础。

#include <iostream>
#include <memory>

// 产品接口
class Product {
public:
    virtual ~Product() = default;
    virtual void operation() = 0;
};

// 具体产品A
class ConcreteProductA : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductA operation" << std::endl;
    }
};

// 具体产品B
class ConcreteProductB : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductB operation" << std::endl;
    }
};

// 简单工厂
class SimpleFactory {
public:
    enum ProductType { A, B };
    
    static std::unique_ptr<Product> createProduct(ProductType type) {
        switch (type) {
            case A: return std::make_unique<ConcreteProductA>();
            case B: return std::make_unique<ConcreteProductB>();
            default: return nullptr;
        }
    }
};

int main() {
    auto productA = SimpleFactory::createProduct(SimpleFactory::A);
    productA->operation();  // 输出: ConcreteProductA operation
    
    auto productB = SimpleFactory::createProduct(SimpleFactory::B);
    productB->operation();  // 输出: ConcreteProductB operation
    
    return 0;
}

2. 工厂方法模式(Factory Method)

工厂方法模式定义了一个创建对象的接口,但让子类决定实例化哪一个类。

#include <iostream>
#include <memory>

// 产品接口
class Product {
public:
    virtual ~Product() = default;
    virtual void operation() = 0;
};

// 具体产品A
class ConcreteProductA : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductA operation" << std::endl;
    }
};

// 具体产品B
class ConcreteProductB : public Product {
public:
    void operation() override {
        std::cout << "ConcreteProductB operation" << std::endl;
    }
};

// 工厂接口
class Factory {
public:
    virtual ~Factory() = default;
    virtual std::unique_ptr<Product> createProduct() = 0;
};

// 具体工厂A
class ConcreteFactoryA : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductA>();
    }
};

// 具体工厂B
class ConcreteFactoryB : public Factory {
public:
    std::unique_ptr<Product> createProduct() override {
        return std::make_unique<ConcreteProductB>();
    }
};

int main() {
    std::unique_ptr<Factory> factoryA = std::make_unique<ConcreteFactoryA>();
    auto productA = factoryA->createProduct();
    productA->operation();  // 输出: ConcreteProductA operation
    
    std::unique_ptr<Factory> factoryB = std::make_unique<ConcreteFactoryB>();
    auto productB = factoryB->createProduct();
    productB->operation();  // 输出: ConcreteProductB operation
    
    return 0;
}

3. 抽象工厂模式(Abstract Factory)

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

#include <iostream>
#include <memory>

// 抽象产品A
class AbstractProductA {
public:
    virtual ~AbstractProductA() = default;
    virtual void operationA() = 0;
};

// 具体产品A1
class ProductA1 : public AbstractProductA {
public:
    void operationA() override {
        std::cout << "ProductA1 operationA" << std::endl;
    }
};

// 具体产品A2
class ProductA2 : public AbstractProductA {
public:
    void operationA() override {
        std::cout << "ProductA2 operationA" << std::endl;
    }
};

// 抽象产品B
class AbstractProductB {
public:
    virtual ~AbstractProductB() = default;
    virtual void operationB() = 0;
};

// 具体产品B1
class ProductB1 : public AbstractProductB {
public:
    void operationB() override {
        std::cout << "ProductB1 operationB" << std::endl;
    }
};

// 具体产品B2
class ProductB2 : public AbstractProductB {
public:
    void operationB() override {
        std::cout << "ProductB2 operationB" << std::endl;
    }
};

// 抽象工厂
class AbstractFactory {
public:
    virtual ~AbstractFactory() = default;
    virtual std::unique_ptr<AbstractProductA> createProductA() = 0;
    virtual std::unique_ptr<AbstractProductB> createProductB() = 0;
};

// 具体工厂1
class ConcreteFactory1 : public AbstractFactory {
public:
    std::unique_ptr<AbstractProductA> createProductA() override {
        return std::make_unique<ProductA1>();
    }
    
    std::unique_ptr<AbstractProductB> createProductB() override {
        return std::make_unique<ProductB1>();
    }
};

// 具体工厂2
class ConcreteFactory2 : public AbstractFactory {
public:
    std::unique_ptr<AbstractProductA> createProductA() override {
        return std::make_unique<ProductA2>();
    }
    
    std::unique_ptr<AbstractProductB> createProductB() override {
        return std::make_unique<ProductB2>();
    }
};

int main() {
    std::unique_ptr<AbstractFactory> factory1 = std::make_unique<ConcreteFactory1>();
    auto productA1 = factory1->createProductA();
    auto productB1 = factory1->createProductB();
    productA1->operationA();  // 输出: ProductA1 operationA
    productB1->operationB();  // 输出: ProductB1 operationB
    
    std::unique_ptr<AbstractFactory> factory2 = std::make_unique<ConcreteFactory2>();
    auto productA2 = factory2->createProductA();
    auto productB2 = factory2->createProductB();
    productA2->operationA();  // 输出: ProductA2 operationA
    productB2->operationB();  // 输出: ProductB2 operationB
    
    return 0;
}

实际案例:数据库连接管理

通过数据库连接这个实际场景,详细分析三种模式的实现和区别。假设我们需要开发一个支持多种数据库(MySQL、PostgreSQL、SQLite)的连接管理系统。

1. 简单工厂模式实现

#include <iostream>
#include <memory>
#include <string>

// 数据库连接接口
class DatabaseConnection {
public:
    virtual ~DatabaseConnection() = default;
    virtual void connect() = 0;
    virtual void executeQuery(const std::string& query) = 0;
};

// MySQL连接
class MySQLConnection : public DatabaseConnection {
public:
    void connect() override {
        std::cout << "Connected to MySQL database" << std::endl;
    }
    void executeQuery(const std::string& query) override {
        std::cout << "Executing MySQL query: " << query << std::endl;
    }
};

// PostgreSQL连接
class PostgreSQLConnection : public DatabaseConnection {
public:
    void connect() override {
        std::cout << "Connected to PostgreSQL database" << std::endl;
    }
    void executeQuery(const std::string& query) override {
        std::cout << "Executing PostgreSQL query: " << query << std::endl;
    }
};

// 简单数据库工厂
class DatabaseFactory {
public:
    enum DBType { MYSQL, POSTGRESQL };
    
    static std::unique_ptr<DatabaseConnection> createConnection(DBType type) {
        switch (type) {
            case MYSQL: return std::make_unique<MySQLConnection>();
            case POSTGRESQL: return std::make_unique<PostgreSQLConnection>();
            default: throw std::invalid_argument("Unknown database type");
        }
    }
};

// 客户端代码
int main() {
    auto mysqlConn = DatabaseFactory::createConnection(DatabaseFactory::MYSQL);
    mysqlConn->connect();
    mysqlConn->executeQuery("SELECT * FROM users");
    
    auto pgConn = DatabaseFactory::createConnection(DatabaseFactory::POSTGRESQL);
    pgConn->connect();
    pgConn->executeQuery("SELECT * FROM customers");
    
    return 0;
}

简单工厂特点分析

  • 一个工厂类负责所有产品的创建

  • 通过参数判断创建哪种产品

  • 新增数据库类型需要修改工厂类(违反开闭原则)

  • 适用于产品较少且不常变化的场景

2. 工厂方法模式实现

// 前面DatabaseConnection及其子类定义不变...

// 抽象工厂接口
class DatabaseFactory {
public:
    virtual ~DatabaseFactory() = default;
    virtual std::unique_ptr<DatabaseConnection> createConnection() = 0;
};

// MySQL工厂
class MySQLFactory : public DatabaseFactory {
public:
    std::unique_ptr<DatabaseConnection> createConnection() override {
        return std::make_unique<MySQLConnection>();
    }
};

// PostgreSQL工厂
class PostgreSQLFactory : public DatabaseFactory {
public:
    std::unique_ptr<DatabaseConnection> createConnection() override {
        return std::make_unique<PostgreSQLConnection>();
    }
};

// 新增SQLite支持不需要修改已有代码
class SQLiteConnection : public DatabaseConnection {
public:
    void connect() override {
        std::cout << "Connected to SQLite database" << std::endl;
    }
    void executeQuery(const std::string& query) override {
        std::cout << "Executing SQLite query: " << query << std::endl;
    }
};

class SQLiteFactory : public DatabaseFactory {
public:
    std::unique_ptr<DatabaseConnection> createConnection() override {
        return std::make_unique<SQLiteConnection>();
    }
};

// 客户端代码
void clientCode(DatabaseFactory& factory) {
    auto conn = factory.createConnection();
    conn->connect();
    conn->executeQuery("SELECT * FROM products");
}

int main() {
    MySQLFactory mysqlFactory;
    clientCode(mysqlFactory);
    
    PostgreSQLFactory pgFactory;
    clientCode(pgFactory);
    
    SQLiteFactory sqliteFactory;
    clientCode(sqliteFactory);
    
    return 0;
}

工厂方法特点分析

  • 每个产品对应一个具体工厂类

  • 新增数据库类型只需添加新工厂类(符合开闭原则)

  • 客户端依赖抽象工厂接口,不依赖具体类

  • 适合产品类型可能扩展的场景

3. 抽象工厂模式实现

现在需求升级:除了数据库连接,还需要支持不同数据库的数据迁移工具

// 数据库连接接口及实现同上...

// 数据迁移工具接口
class DataMigrationTool {
public:
    virtual ~DataMigrationTool() = default;
    virtual void migrate(const std::string& table) = 0;
};

// MySQL迁移工具
class MySQLMigrationTool : public DataMigrationTool {
public:
    void migrate(const std::string& table) override {
        std::cout << "Migrating MySQL table: " << table << std::endl;
    }
};

// PostgreSQL迁移工具
class PostgreSQLMigrationTool : public DataMigrationTool {
public:
    void migrate(const std::string& table) override {
        std::cout << "Migrating PostgreSQL table: " << table << std::endl;
    }
};

// 抽象工厂接口
class DatabaseFactory {
public:
    virtual ~DatabaseFactory() = default;
    virtual std::unique_ptr<DatabaseConnection> createConnection() = 0;
    virtual std::unique_ptr<DataMigrationTool> createMigrationTool() = 0;
};

// MySQL产品族工厂
class MySQLFactory : public DatabaseFactory {
public:
    std::unique_ptr<DatabaseConnection> createConnection() override {
        return std::make_unique<MySQLConnection>();
    }
    std::unique_ptr<DataMigrationTool> createMigrationTool() override {
        return std::make_unique<MySQLMigrationTool>();
    }
};

// PostgreSQL产品族工厂
class PostgreSQLFactory : public DatabaseFactory {
public:
    std::unique_ptr<DatabaseConnection> createConnection() override {
        return std::make_unique<PostgreSQLConnection>();
    }
    std::unique_ptr<DataMigrationTool> createMigrationTool() override {
        return std::make_unique<PostgreSQLMigrationTool>();
    }
};

// 客户端代码
void clientCode(DatabaseFactory& factory) {
    auto conn = factory.createConnection();
    auto tool = factory.createMigrationTool();
    
    conn->connect();
    conn->executeQuery("SELECT * FROM products");
    tool->migrate("users");
}

int main() {
    MySQLFactory mysqlFactory;
    clientCode(mysqlFactory);
    
    PostgreSQLFactory pgFactory;
    clientCode(pgFactory);
    
    return 0;
}

抽象工厂特点分析

  • 创建的是产品族(多个相关产品)

  • 每个具体工厂负责创建一组相关产品

  • 保证产品之间的兼容性

  • 适合需要创建多个相关对象的复杂系统

三者的核心区别总结

特性简单工厂模式工厂方法模式抽象工厂模式
工厂角色一个具体工厂类多个具体工厂类多个具体工厂类(产品族工厂)
扩展性修改工厂类(违反开闭原则)新增工厂类(符合开闭原则)新增产品族工厂(符合开闭原则)
创建目标单一产品单一产品产品族(多个相关产品)
适用场景产品类型固定的小型系统需要灵活扩展产品的系统需要保证产品兼容性的复杂系统
复杂度简单中等较高
产品间约束有(保证产品族兼容性)

选择建议

  1. 如果产品类型固定不变数量少简单工厂

  2. 如果产品类型可能扩展工厂方法

  3. 如果需要创建多个相关产品对象(产品族)→ 抽象工厂

  4. 在大型系统中,三种模式可能组合使用

工厂方法模式是抽象工厂模式的基础,而抽象工厂模式通常包含多个工厂方法。理解这些差异可以帮助你在实际开发中选择最合适的模式。

工厂模式的应用场景

  1. 简单工厂模式

    • 当对象的创建逻辑比较简单时

    • 客户端不需要知道具体的产品类名

  2. 工厂方法模式

    • 当一个类不知道它所需要的对象的类时

    • 当一个类希望由它的子类来指定它所创建的对象时

    • 当将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时

  3. 抽象工厂模式

    • 系统需要独立于它的产品的创建、组合和表示时

    • 系统需要由多个产品系列中的一个来配置时

    • 当需要强调一系列相关的产品对象的设计以便进行联合使用时

    • 当提供一个产品类库,而只想显示它们的接口而不是实现时

工厂模式的优点

  1. 封装性好:客户端不需要知道具体产品类的类名,只需要知道工厂类即可

  2. 扩展性好:增加新的产品时,只需要扩展一个工厂类即可

  3. 解耦:工厂模式将对象的创建与使用分离

  4. 符合开闭原则:对扩展开放,对修改关闭

工厂模式的缺点

  1. 增加复杂度:每增加一个产品,就需要增加一个具体产品类和工厂类

  2. 抽象性增加:引入了抽象层,增加了系统的抽象性和理解难度

  3. 具体产品与工厂耦合:工厂方法模式中,具体产品与具体工厂一一对应

工厂模式是C++中非常常用的设计模式,特别是在需要灵活创建对象的场景中。理解并合理运用工厂模式,可以大大提高代码的可维护性和扩展性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值