C++实现设计模式---工厂方法模式 (Factory Method)

工厂方法模式 (Factory Method)

工厂方法模式是一种创建型设计模式,提供一个创建对象的接口,让子类决定实例化哪个类,从而实现了对对象创建过程的解耦和扩展。


意图

  • 定义一个用于创建对象的接口,允许子类决定具体实例化哪个类。
  • 把对象创建的职责交给子类,使得系统更灵活,符合 开闭原则。

使用场景

  1. 运行时决定类的实例化
    • 如果对象的具体类型在编译时无法确定,而需要在运行时根据条件选择。
  2. 隐藏对象的复杂创建过程
    • 如果创建对象的过程复杂且容易重复,可以使用工厂方法集中管理。
  3. 需要对对象的创建进行扩展
    • 当需要新增产品类时,可以通过增加新的具体工厂类,而不修改已有代码。

参与者角色

  1. 工厂基类 (Creator)

    • 定义创建产品对象的接口,通常包含一个抽象的 createProduct() 方法。
    • 有时可以包含产品创建的默认实现。
  2. 具体工厂类 (Concrete Creator)

    • 实现 createProduct() 方法,负责实例化具体的产品。
  3. 产品基类 (Product)

    • 定义所有产品的公共接口。
  4. 具体产品类 (Concrete Product)

    • 实现产品基类的接口,提供产品的具体功能。

示例代码

以下示例通过工厂方法模式实现了动态创建产品的功能。

cpp 复制代码
#include <iostream>
#include <memory>

// 产品基类
class Product {
public:
    virtual void use() const = 0;
    virtual ~Product() {}
};

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

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

// 工厂基类
class Factory {
public:
    virtual std::unique_ptr<Product> createProduct() const = 0;
    virtual ~Factory() {}
};

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

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

// 主函数
int main() {
    FactoryA factoryA;
    FactoryB factoryB;

    auto productA = factoryA.createProduct();
    auto productB = factoryB.createProduct();

    productA->use(); // 输出:Using Product A
    productB->use(); // 输出:Using Product B

    return 0;
}

代码解析

1. 产品基类

定义了所有产品的公共接口,确保具体产品具有一致的功能。例如:

cpp 复制代码
class Product {
public:
    virtual void use() const = 0;
    virtual ~Product() {}
};

2. 具体产品类

具体产品类实现了产品基类接口,并提供具体的功能实现:

cpp 复制代码
class ConcreteProductA : public Product {
public:
    void use() const override {
        std::cout << "Using Product A" << std::endl;
    }
};

3. 工厂基类

工厂基类声明了创建产品的接口,具体工厂将实现该接口:

cpp 复制代码
class Factory {
public:
    virtual std::unique_ptr<Product> createProduct() const = 0;
    virtual ~Factory() {}
};

4. 具体工厂类

每个具体工厂类实现了 createProduct() 方法,并实例化具体的产品:

cpp 复制代码
class FactoryA : public Factory {
public:
    std::unique_ptr<Product> createProduct() const override {
        return std::make_unique<ConcreteProductA>();
    }
};

5. 主函数

客户端代码通过工厂接口创建产品,而无需知道具体产品的实现细节:

cpp 复制代码
FactoryA factoryA;
auto productA = factoryA.createProduct();
productA->use(); // 输出:Using Product A

优缺点

优点

  1. 符合开闭原则
    • 新增产品只需新增具体工厂类,无需修改已有代码。
  2. 解耦
    • 客户端代码只依赖于工厂接口和产品接口,具体产品的实现细节被隐藏。
  3. 灵活性
    • 可以动态选择和创建具体产品。

缺点

  1. 增加复杂性
    • 每个产品都需要对应的具体工厂类,可能导致类的数量增加。
  2. 需要额外的抽象
    • 增加了工厂基类和产品基类的抽象层。

适用场景

  • 动态选择产品:如根据配置文件决定创建哪个产品。
  • 封装复杂创建过程:如隐藏产品创建的复杂逻辑。
  • 需要扩展性:如未来可能新增产品类型。

改进与扩展

  1. 结合配置文件

    动态读取配置,根据配置内容选择具体工厂:

    cpp 复制代码
    std::unique_ptr<Factory> factory;
    if (config == "A") {
        factory = std::make_unique<FactoryA>();
    } else {
        factory = std::make_unique<FactoryB>();
    }
    auto product = factory->createProduct();
    product->use();
  2. 结合抽象工厂模式

    如果需要创建一组相关的产品,可以将工厂方法扩展为抽象工厂模式。


总结

工厂方法模式通过定义创建对象的接口,将对象的创建与使用分离,提高了代码的扩展性和灵活性。

它适合需要动态选择产品类型或需要隐藏对象创建细节的场景。

相关推荐
殷色玫瑰11 分钟前
C++ string类详解:常用接口、字符串操作与模拟实现
java·linux·c语言·开发语言·数据结构·c++
李游Leo15 分钟前
HarmonyOS 7 + Spatial Recon Kit-C++:3DGS 高斯参数的非有限值隔离与可渲染性门禁【鸿蒙心迹】
开发语言·c++·3d·harmonyos
jimy11 小时前
基类没有虚析构函数,基类指针删除派生类对象,行为是未定义的
开发语言·c++
xlq223222 小时前
全面复习2
c++
无名猿2 小时前
移动构造与移动赋值:把资源偷过来
c++·性能优化·内存管理·现代c++·语法基础
All for pursuit.2 小时前
【回溯-7】494.目标和
数据结构·c++·算法·leetcode
白杨尚青2 小时前
C++入门篇(十三):vector(上)——动态数组:构造、空间增长与迭代器失效
开发语言·c++·笔记·算法·stl
染指11103 小时前
135.Agent-多Agent框架-LangChain多智能体(SubAgents子代理)
数据库·人工智能·设计模式·langchain·agent·agents
(Charon)4 小时前
【C++面试】RAII到底是什么:从资源管理理解C++对象生命周期
c++·算法·面试
无名猿4 小时前
成员初始化列表与初始化顺序陷阱:按声明顺序,不是书写顺序
c++·现代c++·语法基础