2、跟学23种设计模式(C++版):工厂方法模式

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它通过定义一个创建对象的接口,让子类决定实例化哪一个类。这样一来,工厂方法将类的实例化推迟到子类。

工厂方法模式包含以下几个角色:

1、 抽象产品(Product):定义产品的接口;
2、 具体产品(ConcreteProduct):实现产品接口的具体类;
3、 抽象工厂(Creator):声明工厂方法,返回一个产品类型的对象;
4、 具体工厂(ConcreteCreator):实现工厂方法,返回具体产品的实例;

  • 优点

1、 符合开闭原则:添加新产品时,只需扩展一个新的工厂类,不需修改已有代码;
2、 符合单一职责原则:每个具体工厂类只负责创建对应的产品;
3、 更好的代码复用:将对象的创建逻辑集中在一个类中,便于管理和维护;

  • 缺点

1、 类的数量增加:每增加一种产品都需要增加一个具体工厂类,导致类的数量增多;
2、 增加复杂度:相对于简单工厂模式,工厂方法模式会使系统的结构更加复杂;

应用场景

1、 创建复杂对象:当创建对象的逻辑比较复杂且需要在多个地方使用时,可以使用工厂方法模式;
2、 代码解耦:需要将具体类的创建与使用分离时,使用工厂方法模式可以降低耦合度;
3、 动态决定对象类型:需要在运行时根据某些条件动态决定创建哪种类型的对象时,使用工厂方法模式比较合适;

案例演示

这个案例将模拟一个文档处理应用程序,可以创建不同类型的文档(例如:文本文档和图像文档)。工厂方法模式将用于创建这些文档对象。

1、 抽象产品类

// Document.h
#ifndef DOCUMENT_H
#define DOCUMENT_H

#include <string>

class Document {
public:
    virtual void open() = 0;
    virtual void close() = 0;
    virtual void save() = 0;
    virtual ~Document() = default;
};

#endif // DOCUMENT_H

2.具体产品类

// TextDocument.h
#ifndef TEXTDOCUMENT_H
#define TEXTDOCUMENT_H

#include "Document.h"
#include <iostream>

class TextDocument : public Document {
public:
    void open() override {
        std::cout << "Opening text document..." << std::endl;
    }

    void close() override {
        std::cout << "Closing text document..." << std::endl;
    }

    void save() override {
        std::cout << "Saving text document..." << std::endl;
    }
};

#endif // TEXTDOCUMENT_H

// ImageDocument.h
#ifndef IMAGEDOCUMENT_H
#define IMAGEDOCUMENT_H

#include "Document.h"
#include <iostream>

class ImageDocument : public Document {
public:
    void open() override {
        std::cout << "Opening image document..." << std::endl;
    }

    void close() override {
        std::cout << "Closing image document..." << std::endl;
    }

    void save() override {
        std::cout << "Saving image document..." << std::endl;
    }
};

#endif // IMAGEDOCUMENT_H

3.抽象工厂类


// Application.h
#ifndef APPLICATION_H
#define APPLICATION_H

#include "Document.h"
#include <memory>

class Application {
public:
    virtual std::unique_ptr<Document> createDocument() = 0;
    virtual ~Application() = default;
};

#endif // APPLICATION_H

4.具体工厂类


// TextApplication.h
#ifndef TEXTAPPLICATION_H
#define TEXTAPPLICATION_H

#include "Application.h"
#include "TextDocument.h"

class TextApplication : public Application {
public:
    std::unique_ptr<Document> createDocument() override {
        return std::make_unique<TextDocument>();
    }
};

#endif // TEXTAPPLICATION_H

// ImageApplication.h
#ifndef IMAGEAPPLICATION_H
#define IMAGEAPPLICATION_H

#include "Application.h"
#include "ImageDocument.h"

class ImageApplication : public Application {
public:
    std::unique_ptr<Document> createDocument() override {
        return std::make_unique<ImageDocument>();
    }
};

#endif // IMAGEAPPLICATION_H

5.客户端代码


// main.cpp
#include "TextApplication.h"
#include "ImageApplication.h"
#include <iostream>

void processDocument(Application& app) {
    auto doc = app.createDocument();
    doc->open();
    doc->save();
    doc->close();
}

int main() {
    TextApplication textApp;
    ImageApplication imageApp;

    std::cout << "Processing text document:" << std::endl;
    processDocument(textApp);

    std::cout << "\nProcessing image document:" << std::endl;
    processDocument(imageApp);

    return 0;
}

运行结果

Processing text document:
Opening text document...
Saving text document...
Closing text document...

Processing image document:
Opening image document...
Saving image document...
Closing image document...

代码简述

1、 Document:抽象产品类,声明了文档的基本操作接口;
2、 TextDocumentImageDocument:具体产品类,实现了具体类型文档的操作;
3、 Application:抽象工厂类,声明了创建文档对象的接口;
4、 TextApplicationImageApplication:具体工厂类,实现了创建具体类型文档的逻辑;
5、 processDocument函数:客户端代码,接收一个工厂对象,通过调用其createDocument方法创建文档对象,并对文档对象进行操作;

这个具体案例展示了如何使用工厂方法模式来创建不同类型的文档对象,并将对象的创建与使用分离,达到了代码解耦和易于扩展的目的。

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: