C++设计模式(工厂模式)

举报
yd_274589494 发表于 2023/09/24 18:25:05 2023/09/24
【摘要】 @TOC 前言本篇文章正式带大家来学习C++中的设计模式,这篇文章主要带大家学习工厂模式。 一、什么是工厂模式工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但将具体对象的实例化延迟到子类或具体工厂类中。工厂模式通过解耦客户端代码和创建具体对象的过程,使客户端代码不需要直接依赖于具体对象的创建方式,而是通过工厂来创建对象,从而提高代码的灵活性和可维...

@TOC


前言

本篇文章正式带大家来学习C++中的设计模式,这篇文章主要带大家学习工厂模式。

一、什么是工厂模式

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但将具体对象的实例化延迟到子类或具体工厂类中。工厂模式通过解耦客户端代码和创建具体对象的过程,使客户端代码不需要直接依赖于具体对象的创建方式,而是通过工厂来创建对象,从而提高代码的灵活性和可维护性。

在C++中,工厂模式可以有多种实现方式,包括简单工厂模式、工厂方法模式和抽象工厂模式。

UML结构图:

在这里插入图片描述

二、简单工厂模式

简单工厂模式通过一个工厂类来封装对象的创建过程。客户端根据不同的参数传递给工厂类,工厂类根据参数的不同来创建不同的具体对象。简单工厂模式的一大优势是将对象的创建逻辑集中到一个工厂类中,客户端代码只需要与工厂类进行交互,而不需要直接与具体对象进行交互。

示例代码:

#include <iostream>

using namespace std;

// 抽象产品接口
class Product
{
public:
	virtual void use() = 0;
};

// 具体产品类A
class ConcreteProductA : public Product 
{
public:
    void use() 
    {
        cout << "Using ConcreteProductA\n";
    }
};

// 具体产品类B
class ConcreteProductB : public Product
{
public:
    void use() 
    {
        cout << "Using ConcreteProductB\n";
    }
};

//工厂类
class Factory
{
public:
    static Product* CreateProduct(int type)
    {
        if (type == 1)
        {
            return new ConcreteProductA();
        }
        else if (type == 2)
        {
            return new ConcreteProductB();
        }
        else
        {
            return NULL;
        }
    }
};

int main(void)
{
    Product* productA = Factory::CreateProduct(1);
    productA->use();

    Product* productB = Factory::CreateProduct(2);
    productB->use();

    delete productA;
    delete productB;

	return 0;
}

三、简单工厂模式优点和缺点

优点:

将对象的创建逻辑集中到了一个工厂类中,客户端只需要与工厂类进行交互,而无需关注具体对象的创建过程,降低了客户端代码的复杂性。

客户端代码与具体对象解耦,可以通过工厂类创建不同的对象,而无需修改客户端代码,提高了代码的灵活性和可扩展性。

客户端代码只需要知道抽象产品接口,而无需了解具体产品的细节,实现了依赖倒置原则。
可以隐藏具体产品的实现细节,提高了代码的安全性。

缺点:

违反了开闭原则,对于每个新增的具体产品,都需要修改工厂类的创建逻辑,可能导致工厂类的代码过于臃肿。

工厂类集中了所有的对象创建逻辑,当有多个具体产品时,工厂类的代码会变得复杂,不易于维护和扩展。
简单工厂模式中的工厂类负责创建所有具体产品,当新增具体产品时,工厂类会变得臃肿,不符合单一职责原则。

四、简单工厂适用场景

1.对象的创建逻辑相对简单:当需要创建的对象逻辑比较简单,不涉及复杂的条件判断或算法时,可以使用简单工厂模式。

2.需要对客户端代码隐藏具体对象的创建细节:通过简单工厂模式,客户端只需要与工厂类进行交互,而不需要直接与具体对象进行交互,可以实现对具体对象的创建细节进行封装和隐藏。

3.需要根据不同的参数创建不同的对象:当需要根据不同的参数或配置来选择创建不同的具体对象时,可以使用简单工厂模式。客户端只需要给定相应的参数,工厂类根据参数的不同来创建对应的对象。

4.对象的数量相对稳定:如果系统中的对象数量固定且不经常变化,不需要频繁地添加新的具体对象,简单工厂模式可以简化对象的创建和管理。

五、简单工厂类的使用

在Qt中,使用工厂模式可以实现创建和管理各种对象的过程,尤其在UI编程中非常常见。以下是一个简单的示例,展示了如何在Qt中使用工厂模式来创建不同类型的窗口:

首先,我们需要定义一个抽象窗口类(AbstractWindow)作为工厂的产品接口,用于表示不同类型的窗口对象。

class AbstractWindow : public QWidget
{
public:
    virtual void display() = 0;
};

接下来,我们可以创建具体的窗口类(例如:MainWindow、DialogWindow、PopupWindow)继承自抽象窗口类,并实现其相应的方法。

class MainWindow : public AbstractWindow
{
public:
    void display() override
    {
        // 实现MainWindow的显示逻辑
    }
};

class DialogWindow : public AbstractWindow
{
public:
    void display() override
    {
        // 实现DialogWindow的显示逻辑
    }
};

class PopupWindow : public AbstractWindow
{
public:
    void display() override
    {
        // 实现PopupWindow的显示逻辑
    }
};

接下来,我们需要创建一个窗口工厂类(WindowFactory),用于根据不同的参数创建相应类型的窗口对象。

class WindowFactory
{
public:
    static AbstractWindow* createWindow(const QString& windowType)
    {
        if (windowType == "MainWindow")
        {
            return new MainWindow();
        }
        else if (windowType == "DialogWindow")
        {
            return new DialogWindow();
        }
        else if (windowType == "PopupWindow")
        {
            return new PopupWindow();
        }

        return nullptr;
    }
};

在客户端代码中,我们可以使用窗口工厂类来创建具体的窗口对象。

QString windowType = "MainWindow"; // 可以根据需求指定不同的窗口类型

AbstractWindow* window = WindowFactory::createWindow(windowType);
if (window)
{
    window->display();
    delete window;
}

通过上述代码,我们可以根据不同的窗口类型使用工厂模式创建相应的窗口对象,并执行其特定的显示逻辑。

在这个例子中,抽象窗口类充当了工厂的产品接口,具体窗口类是工厂所创建的产品,而窗口工厂类则是具体实现工厂模式的类。通过使用工厂模式,我们能够有效地解耦了窗口对象的创建和使用过程,并使得程序更具灵活性和可扩展性。

总结

本篇文章就讲解到这里。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。