工厂模式(Factory Pattern)是C++中常用的创建型设计模式,它提供了一种创建对象的最佳方式,将对象的创建与使用分离,通过专门的工厂类来负责对象的实例化,从而提高代码的灵活性和可维护性。

工厂模式的核心思想

  • 封装对象创建的细节,客户端无需知道具体类名
  • 通过统一的接口创建不同类型的对象
  • 符合"开放-封闭原则",便于扩展新类型

工厂模式的三种主要形式

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

由一个工厂类根据传入的参数决定创建哪种产品类的实例。

#include <iostream>
#include <string>

// 抽象产品类
class Product {
public:
    virtual void use() = 0;
    virtual ~Product() = default;
};

// 具体产品A
class ProductA : public Product {
public:
    void use() override {
        std::cout << "使用产品A" << std::endl;
    }
};

// 具体产品B
class ProductB : public Product {
public:
    void use() override {
        std::cout << "使用产品B" << std::endl;
    }
};

// 简单工厂类
class SimpleFactory {
public:
    // 根据类型创建产品
    Product* createProduct(const std::string& type) {
        if (type == "A") {
            return new ProductA();
        } else if (type == "B") {
            return new ProductB();
        }
        return nullptr;
    }
};

// 客户端使用
int main() {
    SimpleFactory factory;
    
    Product* productA = factory.createProduct("A");
    Product* productB = factory.createProduct("B");
    
    productA->use();  // 输出:使用产品A
    productB->use();  // 输出:使用产品B
    
    delete productA;
    delete productB;
    return 0;
}
2. 工厂方法模式(Factory Method)

定义一个创建对象的接口,但由子类决定要实例化的类。工厂方法使一个类的实例化延迟到其子类。

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

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

#include <iostream>

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

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

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

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

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

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

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

// 具体工厂1,生产产品A1和B1
class ConcreteFactory1 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ProductA1();
    }
    
    AbstractProductB* createProductB() override {
        return new ProductB1();
    }
};

// 具体工厂2,生产产品A2和B2
class ConcreteFactory2 : public AbstractFactory {
public:
    AbstractProductA* createProductA() override {
        return new ProductA2();
    }
    
    AbstractProductB* createProductB() override {
        return new ProductB2();
    }
};

// 客户端使用
int main() {
    AbstractFactory* factory1 = new ConcreteFactory1();
    AbstractFactory* factory2 = new ConcreteFactory2();
    
    AbstractProductA* productA1 = factory1->createProductA();
    AbstractProductB* productB1 = factory1->createProductB();
    
    AbstractProductA* productA2 = factory2->createProductA();
    AbstractProductB* productB2 = factory2->createProductB();
    
    productA1->use();  // 输出:使用产品A1
    productB1->eat();  // 输出:吃产品B1
    productA2->use();  // 输出:使用产品A2
    productB2->eat();  // 输出:吃产品B2
    
    // 释放资源
    delete productA1;
    delete productB1;
    delete productA2;
    delete productB2;
    delete factory1;
    delete factory2;
    
    return 0;
}

三种工厂模式的对比

  • 简单工厂:实现简单,但新增产品需要修改工厂类,违反开放-封闭原则
  • 工厂方法:每个产品对应一个工厂,新增产品只需新增工厂,符合开放-封闭原则
  • 抽象工厂:用于创建产品家族,适合产品之间有依赖关系的场景

工厂模式的应用场景

  1. 日志记录器:不同格式的日志(文件日志、数据库日志)
  2. 数据库访问:不同数据库(MySQL、Oracle)的连接
  3. UI组件库:跨平台的按钮、文本框等组件
  4. 支付系统:不同支付方式(支付宝、微信支付)

工厂模式的核心价值在于解耦,将对象的创建过程封装起来,使客户端不需要关注具体实现,只需要通过工厂接口获取所需对象,从而提高系统的可扩展性和可维护性。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐