文章目录
- 前言
- 一、什么是工厂模式
- 二、简单工厂模式
- 三、简单工厂模式优点和缺点
- 四、简单工厂适用场景
- 五、简单工厂类的使用
- 总结
前言
本篇文章正式带大家来学习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;
}
通过上述代码,我们可以根据不同的窗口类型使用工厂模式创建相应的窗口对象,并执行其特定的显示逻辑。
在这个例子中,抽象窗口类充当了工厂的产品接口,具体窗口类是工厂所创建的产品,而窗口工厂类则是具体实现工厂模式的类。通过使用工厂模式,我们能够有效地解耦了窗口对象的创建和使用过程,并使得程序更具灵活性和可扩展性。
总结
本篇文章就讲解到这里。