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

news2024/11/24 19:42:04

文章目录

  • 前言
  • 一、什么是工厂模式
  • 二、简单工厂模式
  • 三、简单工厂模式优点和缺点
  • 四、简单工厂适用场景
  • 五、简单工厂类的使用
  • 总结


前言

本篇文章正式带大家来学习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;
}

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

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

总结

本篇文章就讲解到这里。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/923102.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

洗涤护理门店小程序DIY制作教程

随着移动互联网的快速发展&#xff0c;小程序成为了各行各业推广和服务的新平台。对于干洗店来说&#xff0c;拥有一个专属的洗护小程序不仅可以提升用户体验&#xff0c;还能增加店铺的曝光度和销售额。那么&#xff0c;如何DIY制作一个干洗店洗护小程序呢&#xff1f; 首先&a…

在Ubuntu上安装和设置RabbitMQ服务器,轻松实现外部远程访问

文章目录 前言1.安装erlang 语言2.安装rabbitMQ3. 内网穿透3.1 安装cpolar内网穿透(支持一键自动安装脚本)3.2 创建HTTP隧道 4. 公网远程连接5.固定公网TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网TCP端口地址 前言 RabbitMQ是一个在 AMQP(高级消息队列协议)基…

【最全】MySQL知识点总结

先简单的大致了解一下&#xff0c;学习知识的目的是运用&#xff01;&#xff01;&#xff01; MySQL是什么&#xff1f; 一种关系型数据库管理系统&#xff0c;也就是说这是用来管理数据库的工具。 SQL相关命令 数据库相关 创建数据库&#xff1a;CREATE DATABASE 数据库名; …

12、Pinia 快速入门

1、什么是Pinia Pinia 是 Vue 的最新 状态管理工具 &#xff0c;是 Vuex 的 替代品 2、手动添加Pinia到Vue项目 在实际开发项目的时候,关于Pinia的配置,可以在项目创建时自动添加 现在我们初次学习&#xff0c;从零开始&#xff1a; 1.使用 Vite 创建一个空的 Vue3 项目 n…

【JUC系列-02】深入理解CAS底层原理和基本使用

JUC系列整体栏目 内容链接地址【一】深入理解JMM内存模型的底层实现原理https://zhenghuisheng.blog.csdn.net/article/details/132400429【二】深入理解CAS底层原理和基本使用https://blog.csdn.net/zhenghuishengq/article/details/132478786 深入理解cas的底层原理和基本使用…

Bootstrap的类container与类container-fluid有什么区别?

阅读本文前建议先阅读下面两篇博文&#xff1a; 怎么样通过Bootstrap已经编译好(压缩好)的源码去查看符合阅读习惯的源码【通过Source Map(源映射)文件实现】 在CSS中&#xff0c;盒模型中的padding、border、margin是什么意思&#xff1f; 以下是Bootstrap的类 container 的盒…

【Java 高阶】一文精通 Spring MVC - 标签库 (八)

&#x1f449;博主介绍&#xff1a; 博主从事应用安全和大数据领域&#xff0c;有8年研发经验&#xff0c;5年面试官经验&#xff0c;Java技术专家&#xff0c;WEB架构师&#xff0c;阿里云专家博主&#xff0c;华为云云享专家&#xff0c;51CTO 专家博主 ⛪️ 个人社区&#x…

Android——基本控件(下)(十八)

1. 时钟组件&#xff1a;AnalogClock与DigitalClock 1.1 知识点 &#xff08;1&#xff09;掌握AnalogClock与DigitalClock的使用&#xff1b; 1.2 具体内容 package com.example.clockproject;import android.os.Bundle; import android.app.Activity; import android.view…

含泪总结当遇到linux文件系统根目录上的磁盘空间不足怎么办!!

那天写项目代码&#xff0c;cmake编译生成文件的时候给我说磁盘不够了..文件没法生成&#xff0c;因为当时是远程连接的&#xff0c;所以就先断了连接&#xff0c;重启了虚拟机&#xff01;好家伙重启之后因为内存不够&#xff0c;根本进不到gnu界面&#xff0c;就是想重新扩容…

一篇带你肝完Python逆向为什么要学webpack,学完之后到底又该怎么用?

目录 前言简单示例配置示例深入案例分析 总结 前言 大家好&#xff0c;我是辣条哥&#xff01; 之前讲了很多关于基础方面的内容&#xff0c;从本章开始辣条我会开始慢慢开始跟大家解析一些进阶知识以及案例 废话不多说今天我们就深入解析一下webpack&#xff0c;我们先聊一下P…

【LeetCode】 双指针,快慢指针解题

1.删除有序数组中的重复项 class Solution {public int removeDuplicates(int[] nums) {int fast 1;int slow 1;for(;fast<nums.length;fast) {if( nums[fast] !nums[fast-1] ) {nums[slow] nums[fast];slow;}}return slow;} } 2.移除元素 class Solution {public int re…

2023年高教社杯 国赛数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

【MD5加密结果不一致问题】同一个文本字符串,使用MD5加密之后,得出的加密结果居然不相同

目录 1.1、错误描述 1.2、解决方案 1.3、MD5工具类 1.1、错误描述 今天工作中&#xff0c;遇到一个奇怪的问题&#xff0c;我负责对接第三方的短信发送接口&#xff0c;接口中有一个入参是sign加签字段&#xff0c;根据短信内容进行MD5加密 之后得到&#xff0c;于是我就是…

STM32使用PID调速

STM32使用PID调速 PID原理 PID算法是一种闭环控制系统中常用的算法&#xff0c;它结合了比例&#xff08;P&#xff09;、积分&#xff08;I&#xff09;和微分&#xff08;D&#xff09;三个环节&#xff0c;以实现对系统的控制。它的目的是使 控制系统的输出值尽可能接近预…

基于Llama2和LangChain构建本地化定制化知识库AI聊天机器人

参考&#xff1a; 本项目 https://github.com/PromtEngineer/localGPT 模型 https://huggingface.co/TheBloke/Llama-2-7B-Chat-GGML 云端知识库项目&#xff1a;基于GPT-4和LangChain构建云端定制化PDF知识库AI聊天机器人_Entropy-Go的博客-CSDN博客 1. 摘要 相比OpenAI的…

背包问题DP(01背包 完全背包 多重背包 分组背包)

目录 背包问题的简介背包问题的定义背包问题的分类 01背包问题典型例题实现思路二维数组代码实现一维数组优化实现扩展&#xff1a;记忆化搜索 DPS 实现 01背包之恰好装满思路代码实现 完全背包问题典型例题思路分析二维数组代码实现一维数组优化实现 多重背包问题多重背包问题…

网易一面:单节点2000Wtps,Kafka怎么做的?

说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如网易、有赞、希音、百度、网易、滴滴的面试资格&#xff0c;遇到一几个很重要的面试题&#xff1a; 问题1&#xff1a;单节点2000Wtps&#xff0c;Kafka高性能原理是什么&#…

测试人员如何通过AI提高工作效率!

随着AI技术的兴起&#xff0c;像OpenAI推出的ChatGPT、Microsoft发布的Microsoft 365 Copilot、阿里的通义千问、百度的文心一言、华为的盘古大模型等。很多测试人员开始担心&#xff0c;岗位是否会被AI取代&#xff1f;其实取代你的不是AI&#xff0c;而是会使用AI的测试人&am…

[论文分享]VOLO: Vision Outlooker for Visual Recognition

VOLO: Vision Outlooker for Visual Recognition 概述 视觉 transformer&#xff08;ViTs&#xff09;在视觉识别领域得到了广泛的探索。由于编码精细特征的效率较低&#xff0c;当在 ImageNet 这样的中型数据集上从头开始训练时&#xff0c;ViT 的性能仍然不如最先进的 CNN。…

解密长短时记忆网络(LSTM):从理论到PyTorch实战演示

目录 1. LSTM的背景人工神经网络的进化循环神经网络&#xff08;RNN&#xff09;的局限性LSTM的提出背景 2. LSTM的基础理论2.1 LSTM的数学原理遗忘门&#xff08;Forget Gate&#xff09;输入门&#xff08;Input Gate&#xff09;记忆单元&#xff08;Cell State&#xff09;…