【C++】—— 工厂模式详解

目录

(一)工厂模式的特点

(二)工厂模式分类

1、简单工厂模式

2、工厂方法模式

3、抽象工厂模式

(三)总结与回顾


(一)工厂模式的特点

 1、优势

  • ⼯⼚模式是⼀种创建型设计模式, 它提供了⼀种创建对象的最佳⽅式;
  • 在⼯⼚模式中,我们创建对象时不会对上层暴露创建逻辑,⽽是通过使⽤⼀个共同结构来指向新创建的对象,以此实现创建-使⽤的分离。
2、缺点
尽管工厂模式在许多情况下是一种有用的设计模式,但它也有一些缺点需要考虑:
  • 除了原来的产品类和客户端代码外,还需要定义工厂接口具体工厂类等额外的类。这可能导致系统变得更加复杂,特别是当需要创建多个不同类型的对象时。
但是尽管工厂模式存在上述缺点,但在许多情况下它仍然是一种有用的设计模式。在实际应用中,我们需要权衡使用工厂模式带来的好处和缺点,并根据具体情况进行选择。

(二)工厂模式分类

工厂模式可以分为三种不同的类型:简单工厂模式工厂方法模式抽象工厂模式

1、简单工厂模式

简单⼯⼚模式实现由⼀个⼯⼚对象通过类型决定创建出来指定产品类的实例。
  • 假设有个⼯⼚能⽣产出⽔果,当客⼾需要产品的时候明确告知⼯⼚⽣产哪类⽔果,⼯⼚需要接收⽤⼾提供的类别信息,当新增产品的时候,⼯⼚内部去添加新产品的⽣产⽅式。
接下来,我们看代码演示:
#include<iostream>
#include <string>
#include <memory>class Fruit{public:Fruit(){}virtual void show() = 0;
};
class Apple : public Fruit{public:Apple(){}virtual void show(){std::cout << "我是一个苹果" << std::endl;}
};class Banana : public Fruit{public:Banana(){}virtual void show(){std::cout << "我是一个香蕉" << std::endl;}
};class FruitFactory{public:static std::shared_ptr<Fruit> create(const std::string &name){if(name == "苹果"){return std::make_shared<Apple>();}else if(name == "香蕉"){return std::make_shared<Banana>();}else{return std::shared_ptr<Fruit>(); }}
};
int main()
{std::shared_ptr<Fruit> fruit = FruitFactory::create("苹果");fruit->show();fruit = FruitFactory::create("香蕉");fruit->show();return 0;
}

运行结果如下:

【小结】
简单⼯⼚模式:通过参数控制可以⽣产任何产品

优点

  • 简单粗暴,直观易懂。使⽤⼀个⼯⼚⽣产同⼀等级结构下的任意产品
  缺点
  • 1. 所有东西⽣产在⼀起,产品太多会导致代码量庞⼤
  • 2. 开闭原则遵循(开放拓展,关闭修改)的不是太好,要新增产品就必须修改⼯⼚⽅法。

2、工厂方法模式

工厂方法模式定义一个创建对象的接口,但将实际的实例化延迟到子类中。每个子类都可以根据需要创建适合自身的对象。

  • 假设现在有A、B 两种产品,则开两个⼯⼚,⼯⼚ A 负责⽣产产品 A,⼯⼚ B 负责⽣产产品 B,⽤⼾只知道产品的⼯⼚名,⽽不知道具体的产品信息,⼯⼚不需要再接收客⼾的产品类别,⽽只负责⽣产产品。

接下来,我们还是看代码演示:

#include<iostream>
#include <string>
#include <memory>class Fruit{public:Fruit(){}virtual void show() = 0;
};
class Apple : public Fruit{public:Apple(){}virtual void show(){std::cout << "我是一个苹果" << std::endl;}
};class Banana : public Fruit{public:Banana(){}virtual void show(){std::cout << "我是一个香蕉" << std::endl;}
};//工厂模式方法class FruitFactory{public:virtual std::shared_ptr<Fruit> create() = 0;
};class AppleFactory : public FruitFactory{public:virtual std::shared_ptr<Fruit> create(){return std::make_shared<Apple>();}
};class BananaFactory : public FruitFactory{public:virtual std::shared_ptr<Fruit> create(){return std::make_shared<Banana>();}
};int main()
{std::shared_ptr<FruitFactory> factory(new AppleFactory());std::shared_ptr<Fruit> fruit = factory->create();fruit->show();factory.reset(new BananaFactory());fruit = factory->create();fruit->show();return 0;
}

运行结果如下:

【小结】

⼯⼚⽅法:定义⼀个创建对象的接⼝,但是由⼦类来决定创建哪种对象,使⽤多个⼯⼚分别⽣产指定 的固定产品
优点
  • 1. 减轻了⼯⼚类的负担,将某类产品的⽣产交给指定的⼯⼚来进⾏
  • 2. 开闭原则遵循较好,添加新产品只需要新增产品的⼯⼚即可,不需要修改原先的⼯⼚类
缺点
  • 对于某种可以形成⼀组产品族的情况处理较为复杂,需要创建⼤量的⼯⼚类

⼯⼚⽅法模式通过引⼊⼯⼚等级结构,解决了简单⼯⼚模式中⼯⼚类职责太重的问题,但由于⼯⼚⽅法模式中的每个⼯⼚只⽣产⼀类产品,可能会导致系统中存在⼤量的⼯⼚类,势必会增加系统的开销。———— 由此就引入了抽象工厂模式。


3、抽象工厂模式

可以考虑将⼀些相关的产品组成⼀个产品族(位于不同产品等级 结构中功能相关联的产品组成的家族),由同⼀个⼯⼚来统⼀⽣产,这就是抽象⼯⼚模式的基本思想。

接下来,我们还是看代码演示:

#include<iostream>
#include <string>
#include <memory>//产品类一:水果
class Fruit{public:Fruit(){}virtual void show() = 0;
};
class Apple : public Fruit{public:Apple(){}virtual void show(){std::cout << "我是一个苹果" << std::endl;}
};class Banana : public Fruit{public:Banana(){}virtual void show(){std::cout << "我是一个香蕉" << std::endl;}
};//产品类二:动物
class Animal {public:virtual void voice() = 0;
};class Lamp: public Animal {public:void voice() override { std::cout << "咩咩咩\n"; }
};class Dog: public Animal {public:void voice() override { std::cout << "汪汪汪\n"; }
};class Factory {public:virtual std::shared_ptr<Fruit> getFruit(const std::string &name) = 0;virtual std::shared_ptr<Animal> getAnimal(const std::string &name) = 0;
};class FruitFactory : public Factory {public:virtual std::shared_ptr<Animal> getAnimal(const std::string &name) {return std::shared_ptr<Animal>();}virtual std::shared_ptr<Fruit> getFruit(const std::string &name) {if (name == "苹果") {return std::make_shared<Apple>();}else if(name == "⾹蕉") {return std::make_shared<Banana>();}return std::shared_ptr<Fruit>();}
};class AnimalFactory : public Factory {public:virtual std::shared_ptr<Fruit> getFruit(const std::string &name) {return std::shared_ptr<Fruit>();}virtual std::shared_ptr<Animal> getAnimal(const std::string &name) {if (name == "⼩⽺") {return std::make_shared<Lamp>();}else if(name == "⼩狗") {return std::make_shared<Dog>();}return std::shared_ptr<Animal>();}
};class FactoryProducer {public:static std::shared_ptr<Factory> getFactory(const std::string &name) {if (name == "动物") {return std::make_shared<AnimalFactory>();}else {return std::make_shared<FruitFactory>();}   }
};int main()
{std::shared_ptr<Factory> fruit_factory = FactoryProducer::getFactory("⽔果");std::shared_ptr<Fruit> fruit = fruit_factory->getFruit("苹果");fruit->show();fruit = fruit_factory->getFruit("⾹蕉");fruit->show();std::shared_ptr<Factory> animal_factory = FactoryProducer::getFactory("动物");std::shared_ptr<Animal> animal = animal_factory->getAnimal("⼩⽺");animal->voice();animal = animal_factory->getAnimal("⼩狗");animal->voice();return 0;
}

运行结果如下:

【小结】

抽象⼯⼚:围绕⼀个超级⼯⼚创建其他⼯⼚。每个⽣成的⼯⼚按照⼯⼚模式提供对象。

抽象⼯⼚模式适⽤于⽣产多个⼯⼚系列产品衍⽣的设计模式,增加新的产品等级结构复杂,需要对原有系统进⾏较⼤的修改,甚⾄需要修改抽象层代码,违背了“开闭原则”。

 


(三)总结与回顾

以上便是本文关于工厂模式的全部内容,接下来简单回顾总结下本文都讲到了什么!!!

工厂模式是一种创建型设计模式,旨在封装对象的实例化过程,使得客户端代码与具体类的实例化过程解耦,从而提高代码的可维护性、可扩展性和灵活性;

优势:

  1. 解耦: 工厂模式能够将对象的创建和使用分离,降低了客户端与具体类之间的耦合度。

  2. 可维护性: 当需要修改或扩展具体类时,只需修改工厂类而不影响客户端代码,提高了系统的可维护性。

  3. 扩展性: 可通过增加新的具体工厂和具体产品来扩展系统,符合开闭原则。

  4. 代码复用: 工厂模式促进了代码的复用,因为客户端通过接口或基类与工厂类交互,而不直接与具体类交互。

适用场景:

  1. 对象的创建逻辑复杂: 当对象的创建涉及一系列复杂的步骤或条件判断时,使用工厂模式可以将这些复杂性封装起来。

  2. 需要根据条件动态创建对象: 当需要根据不同条件来创建不同类型的对象时,工厂模式是一个有效的选择。

  3. 系统需要更高的灵活性和可扩展性: 工厂模式允许系统在不修改客户端代码的情况下引入新的产品类和工厂类,提供了系统的可扩展性。

到此,本文的内容全部讲解结束。感谢大家的观看与支持!!!

 

 

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

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

相关文章

快速入门Visual Studio 2022开发.Net Framework研发环境指南

IDE工具 Visual Studio 2022 Vs2022企业版 - VisualStudioSetup.exe Visual Studio Code VSCodeUserSetup-x64-1.66.2.exeVSCodeUserSetup-x64-1.67.0-insider.exe IDE环境 编程字体YaHei.Consolas YaHei.Consolas.1.12.ttf IDE插件 Visual Studio Code常用插件 Chinese…

django项目基础后端功能使用

参考材料 Django新手项目实例-CSDN博客 一、django安装 pip3 install django 二、django项目新建 在目标目下执行 django-admin startproject testdjgo 执行完成后生成对应项目路径 三、django路由功能编写 /xxx/urls.py中编写路由信息&#xff0c;并且把路由转发到对应…

说出来你别不信,盲订问界M9的原因 你们想错了,他们只图这个

文|AUTO芯球 作者|李瑞 怎么还有人说华为是骗子&#xff1f; 华为一张海报说问界M9上市6天&#xff0c;大定超过3万台。有些人就说这是假的&#xff0c;反正没第三方数据&#xff0c;华为可以随便写。 我去&#xff0c;我作为一名大定问界M9的车主&#xff0c;就奉劝哪些黑子…

5.vue学习笔记(数组变化的侦测+计算属性+Class绑定)

文章目录 1.数组变化的侦测1.1.变更方法1.2.替换一个数组 2.计算属性计算属性缓存vs方法 3.Class绑定3.1.绑定对象3.2.多个对象的绑定形式3.3.绑定数组3.4.数组与对象 1.数组变化的侦测 1.1.变更方法 vue能够侦听响应式数组的变更方法&#xff0c;并在它们被调用时出发相关的…

Taro+vue3 实现电影切换列表

1.需求 我们在做类似于猫眼电影的小程序或者H5 的时候 我们会做到那种 左右滑动的电影列表&#xff0c;这种列表一般带有电影场次 2.效果 3.说明 这种效果在淘票票 猫眼电影上 都有的 &#xff0c;一般电影类型的H5 或者小程序 这个是都有的 第一是好看 第二是客观性比较好 …

Mysql InnoDB行锁深入理解

Record Lock记录锁 Record Lock 称为记录锁&#xff0c;锁住的是一条记录。而且记录锁是有 S 锁和 X 锁之分的&#xff1a; 当一个事务对一条记录加了 S 型记录锁后&#xff0c;其他事务也可以继续对该记录加 S 型记录锁&#xff08;S 型与 S 锁兼容&#xff09;&#xff0c;…

物联网与智能家居:跨境电商与未来生活的融合

物联网&#xff08;Internet of Things&#xff0c;IoT&#xff09;和智能家居技术正迅速崛起&#xff0c;成为跨境电商领域的创新引擎。这两者的巧妙结合不仅为消费者提供更智能、便捷的生活方式&#xff0c;同时也为电商平台和制造商带来了全新的商机。本文将深入探讨物联网与…

C++模板——(3)类模板

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 勤奋&#xff0c;机会&#xff0c;乐观…

使用pyinstaller打包生成exe(解决gradio程序的打包问题)

解决 [Errno 2] No such file or directory: gradio_client\types.json 问题&#xff0c;不需要手动创建hook文件 解决 FileNotFoundError: [Errno 2] No such file or directory: gradio\blocks_events.pyc 问题&#xff0c;不需要将pyi文件重命名为pyc文件 最终实现gradio程…

手撕 PCA

PCA&#xff08;Principal Component Analysis&#xff09;&#xff0c;中文名称&#xff1a;主成分分析。迄今为止最流行的降维算法。 假设 n 维空间中的一个单位立方体&#xff0c;易知&#xff1a;一维空间中该立方体中任意两点的距离不超过 1 1 1&#xff0c;二维空间中该…

自动连接校园网(河海大学)

layout: post # 使用的布局&#xff08;不需要改&#xff09; title: 自动连接校园网&#xff08;河海大学&#xff09; # 标题 subtitle: 网络 #副标题 date: 2024-01-09 # 时间 author: BY ThreeStones1029 # 作者 header-img: img/about_bg.jpg #这篇文章标题背景图片 catal…

GAMES101-Assignment4

一、问题总览 实现de Casteljau算法来绘制由4个控制点表示的Bzier曲线。需要修改main.cpp中的如下函数&#xff1a; bezier&#xff1a;该函数实现绘制Bzier曲线的功能。它使用一个控制点序列和一个OpenCV::Mat对象作为输入&#xff0c;没有返回值。它会使t在0到1的范围内进行…

Python采集微博评论做词云图

嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! python更多源码/资料/解答/教程等 点击此处跳转文末名片免费获取 环境使用: Python 3.10 Pycharm 第三方模块使用: import requests >>> pip install requests import wordcloud >>> pip install wordclou…

扩展学习|数据融合助推商务智能与分析

文献来源&#xff1a;[1]李爱华,续维佳,石勇.基于数据融合的商务智能与分析架构研究[J].计算机科学,2022,49(12):185-194. 一、信息融合 &#xff08;一&#xff09;信息融合定义演变 早期信息融合的定义指出&#xff0c;其主要任务是综合分析若干传感器观测到的信息[9,…

微信小程序canvas画布实现矩形元素自由缩放、移动功能

获取画布信息并绘制背景 .whml <canvas class="canvas" type="2d" id="myCanvas" bindtouchstart="get_rect_touch_position" bindtouchmove="move_or_scale" bind:tap="finish_edit_check"/> .wxss .c…

【案例实战】业务稳定性运行之全链路混合压测

1.全链路压测开展步骤 &#xff08;1&#xff09;什么是全链路压测 全链路压测是指基于真实业务场景&#xff0c;通过模拟海量的用户请求&#xff0c;对整个后台服务进行压力测试&#xff0c;从而评估整个系统的性能水平。 对应用程序的整个技术栈进行完整的压力和性能测试&a…

关于24年信息系统项目管理师论文如何提升?

信息系统项目管理师论文满分是75分&#xff0c;45分及以上为及格&#xff0c;论文评分可分为优良、及格与不及格3个档次。 评分的分数可分为&#xff1a; &#xff08;1&#xff09;60分至75分优良&#xff08;相当于百分制80分至100分&#xff09;。 &#xff08;2&#xf…

数模学习day09-cftool使用

老版本的MATLAB可以在命令行使用cftool打开&#xff0c;2017a的版本可以直接找到。 x和y在你的工作区中需要已经存在&#xff0c;然后打开该工具箱就可以看见。 选择X和Y xy选择好之后就自动画好了拟合曲线。 Results分析 画好之后结果就呈现在这里了 这里的p1就是拟合系数&…

用React给XXL-JOB开发一个新皮肤(一):环境搭建和项目初始化

目录 一. 简述二. Fork 项目三. 搭建开发环境四. 初始化皮肤项目五. 添加相关依赖六. 预览 一. 简述 大名鼎鼎的 xxl-job 任务调度中心我们应该都使用过&#xff0c;项目地址&#xff1a;xxl-job。它是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单…