C++设计模式之创建型模式:工厂方法模式(Factory Method)

工厂方法模式(Factory Method)是创建型设计模式的一种,它定义了一个创建对象的接口,但将具体对象的实例化延迟到子类中。这种模式通过封装对象创建过程,实现了"创建与使用分离",提高了代码的灵活性和可扩展性。

核心角色

工厂方法模式包含4个关键角色:

  1. 产品(Product):定义所有具体产品的公共接口。
  2. 具体产品(ConcreteProduct):实现产品接口的具体类。
  3. 工厂(Creator):声明工厂方法(用于创建产品),返回产品类型。
  4. 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品实例。

实现示例

假设我们需要设计一个文档编辑器,支持创建不同类型的文档(如文本文档、表格文档),使用工厂方法模式的实现如下:

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

// 1. 产品接口(Product)
class Document {
public:
    virtual void open() = 0;
    virtual void save() = 0;
    virtual ~Document() = default; // 虚析构函数
};

// 2. 具体产品A(ConcreteProduct)
class TextDocument : public Document {
public:
    void open() override {
        std::cout << "打开文本文档" << std::endl;
    }
    void save() override {
        std::cout << "保存文本文档" << std::endl;
    }
};

// 2. 具体产品B(ConcreteProduct)
class SpreadsheetDocument : public Document {
public:
    void open() override {
        std::cout << "打开表格文档" << std::endl;
    }
    void save() override {
        std::cout << "保存表格文档" << std::endl;
    }
};

// 3. 工厂接口(Creator)
class Application {
public:
    // 工厂方法(纯虚函数,由子类实现)
    virtual Document* createDocument() = 0;
    
    // 业务方法(使用产品)
    void newDocument() {
        Document* doc = createDocument(); // 调用工厂方法创建产品
        doc->open();
        // 其他操作...
        delete doc; // 释放资源
    }
    
    virtual ~Application() = default;
};

// 4. 具体工厂A(ConcreteCreator)
class TextEditor : public Application {
public:
    // 实现工厂方法:创建文本文档
    Document* createDocument() override {
        return new TextDocument();
    }
};

// 4. 具体工厂B(ConcreteCreator)
class SpreadsheetEditor : public Application {
public:
    // 实现工厂方法:创建表格文档
    Document* createDocument() override {
        return new SpreadsheetDocument();
    }
};

// 客户端代码
int main() {
    // 创建文本编辑器(具体工厂)
    Application* textApp = new TextEditor();
    textApp->newDocument(); // 内部会创建文本文档
    
    // 创建表格编辑器(具体工厂)
    Application* sheetApp = new SpreadsheetEditor();
    sheetApp->newDocument(); // 内部会创建表格文档
    
    // 释放资源
    delete textApp;
    delete sheetApp;
    return 0;
}

代码解析

  1. 产品接口(Document) :定义了所有文档的通用行为(open()save())。
  2. 具体产品TextDocumentSpreadsheetDocument 分别实现了文本文档和表格文档的具体功能。
  3. 工厂接口(Application) :声明了工厂方法 createDocument(),并通过 newDocument() 方法使用产品(体现"创建与使用分离")。
  4. 具体工厂TextEditorSpreadsheetEditor 分别实现了创建文本文档和表格文档的工厂方法。

核心优势

  1. 解耦:客户端无需知道具体产品的类名,只需通过工厂接口创建对象。
  2. 可扩展性:新增产品时,只需添加对应的具体产品类和具体工厂类,无需修改现有代码(符合开闭原则)。
  3. 灵活性:通过更换具体工厂,可动态改变程序所使用的产品类型。

适用场景

  1. 当一个类不知道它所需要创建的对象的具体类型时。
  2. 当一个类希望由子类来决定创建哪个对象时。
  3. 当需要集中管理对象的创建逻辑,且未来可能扩展更多产品类型时。

与简单工厂模式的区别

  • 简单工厂:由一个工厂类根据参数创建不同产品,新增产品需修改工厂类(违反开闭原则)。
  • 工厂方法:每个产品对应一个具体工厂,新增产品只需新增工厂类(符合开闭原则)。

工厂方法模式更适合产品类型较多或需要频繁扩展的场景,是对简单工厂模式的进一步抽象和优化。

相关推荐
闻缺陷则喜何志丹15 小时前
【排序 离散化 二维前缀和】 P7149 [USACO20DEC] Rectangular Pasture S|普及+
c++·算法·排序·离散化·二维前缀和
君义_noip15 小时前
信息学奥赛一本通 4163:【GESP2512七级】城市规划 | 洛谷 P14921 [GESP202512 七级] 城市规划
c++·算法·图论·gesp·信息学奥赛
不想写代码的星星15 小时前
C++ 的花括号有多狂?std::initializer_list 那些不讲武德的事儿
c++
两年半的个人练习生^_^15 小时前
每日一学:设计模式之原型模式
java·开发语言·设计模式·原型模式
elseif12315 小时前
初学者必背【考点清单(大全)】【上篇】
开发语言·c++·笔记·学习·循环结构·分支结构·考纲
并不喜欢吃鱼15 小时前
从零开始C++----二.(下篇)模版进阶与编译全过程的复习
开发语言·c++
智者知已应修善业15 小时前
【51单片机按键控制流水灯+数码管显示按键次数】2023-6-15
c++·经验分享·笔记·算法·51单片机
汉克老师15 小时前
GESP2023年12月认证C++三级( 第三部分编程题(1、小猫分鱼))
c++·算法·模拟算法·枚举算法·gesp三级·gesp3级
不知名的老吴15 小时前
View的三大特性之一:迟绑定
开发语言·c++·算法
Huangjin007_16 小时前
【C++ STL篇(四)】一文拿捏vector常用接口!
开发语言·c++·学习