设计模式学习(二)工厂模式——工厂方法模式
设计模式学习(二)工厂模式——工厂方法模式
- 前言
- 工厂方法模式
- 简介
- 示例
- 优点
- 缺点
- 使用场景
前言
前一篇文章介绍了简单工厂模式,提到了简单工厂模式的缺点(违反开闭原则,扩展困难),本文要介绍的工厂方法模式在一定程度上弥补了简单工厂模式的缺点。
工厂方法模式
简介
工厂方法模式是创建型设计模式之一,它在抽象工厂类中声明创建对象的接口,在具体工厂类中实现具体的实例化过程。这个模式的核心思想是将对象的实例化延迟到子类中进行,从而使得父类通过其子类来指定创建哪个对象,实现了类的实例化操作的封装和数据的封装。
这样的话,当要添加一个具体产品时,我们不会修改原有的工厂类(不违反开闭原则),而是新创建一个关联于具体产品的具体工厂类(易扩展)。
示例
抽象相机类:CameraDevice
具体相机类:BaslerCameraDevice,SickCameraDevice,HuarayCameraDevice
抽象工厂类:CameraDeviceFactory
具体工厂类:BaslerCameraFactory,SickCameraFactory,HuarayCameraFactory
UML类图如下:
代码如下:
// 抽象产品类
class CameraDevice
{
public:CameraDevice() = default;virtual ~CameraDevice() = 0;virtual bool Init(){};virtual bool OpenDevice() = 0;
};class BaslerCameraDevice : public CameraDevice
{
public:~BaslerCameraDevice() override;bool Init() override{};bool OpenDevice() override{};
};class HuarayCameraDevice : public CameraDevice
{
public:~HuarayCameraDevice() override{};bool Init() override{};bool OpenDevice() override{};
};class SickCameraDevice : public CameraDevice
{
public:~SickCameraDevice() override{};bool Init() override{};bool OpenDevice() override{};
};// 抽象工厂类
class CameraDeviceFactory
{
public:virtual std::shared_ptr<CameraDevice> CreateCamera() = 0;
};// 具体工厂类
class BaslerCameraFactory : public CameraDeviceFactory
{
public:std::shared_ptr<CameraDevice> CreateCamera() override {return std::make_shared<BaslerCameraDevice>();}
};class HuarayCameraFactory : public CameraDeviceFactory
{
public:std::shared_ptr<CameraDevice> CreateCamera() override {return std::make_shared<HuarayCameraDevice>();}
};class SickCameraFactory : public CameraDeviceFactory
{
public:std::shared_ptr<CameraDevice> CreateCamera() override {return std::make_shared<SickCameraDevice>();}
};int main()
{std::shared_ptr<CameraDeviceFactory> factory = std::make_shared<BaslerCameraFactory>();std::shared_ptr<CameraDevice> camera = factory->CreateCamera();camera->Init();camera->OpenDevice();return 0;
}
优点
- 解耦:工厂方法模式可以减少客户代码与具体类之间的耦合。客户端在使用的时候只需知道接口,而不是具体类。这样可以更容易地扩展或修改创建逻辑,而无需修改现有客户代码。
- 符合开闭原则:工厂方法模式允许系统在不修改现有代码的情况下引入新的类型。满足对扩展开放,对修改封闭的原则。
- 单一职责原则:工厂方法模式中,创建对象的逻辑被封装在一个工厂类中,这符合单一职责原则。这让代码更加清晰,维护也更简单。
缺点
- 代码复杂:工厂方法模式为每种产品类型提供一个单独的工厂类。这意味着每增加一个新的产品类别,就需要增加一个新的具体工厂类。这会导致类的数量迅速增加,从而增加了代码的复杂性
- 代码冗余:如果具体工厂类之间的创建逻辑相似,这可能会导致代码冗余。虽然每个工厂类只负责创建一个具体产品,但这些工厂类的创建逻辑可能高度相似,不能有效地重用代码。
使用场景
- 产品类别经常变化:一个系统会频繁添加或修改产品的创建,而每种产品的创建又有不同的复杂配置和依赖时,工厂方法可以将具体产品的创建逻辑封装在各自的工厂类中,从而简化客户端代码。
相关文章:

设计模式学习(二)工厂模式——工厂方法模式
设计模式学习(二)工厂模式——工厂方法模式 前言工厂方法模式简介示例优点缺点使用场景 前言 前一篇文章介绍了简单工厂模式,提到了简单工厂模式的缺点(违反开闭原则,扩展困难),本文要介绍的工…...

TCP与UDP案例
udp不会做拆分整合什么的 多大就是多大...

Adaboost集成学习 | Matlab实现基于CNN-LSTM-Adaboost集成学习时间序列预测(股票价格预测)
目录 效果一览基本介绍模型设计程序设计参考资料 效果一览 基本介绍 Adaboost集成学习 | Matlab实现基于CNN-LSTM-Adaboost集成学习时间序列预测(股票价格预测) 模型设计 融合Adaboost的CNN-LSTM模型的时间序列预测,下面是一个基本的框架。 …...

你焦虑了吗
前段时间,无意间在图书馆看到一本书《认知觉醒》,书中提到了焦虑的相关话题,从焦虑的根源,焦虑的形式,如何破解焦虑给了我点启示,分享给一下。 引语: 焦虑肯定是你的老朋友了,它总像…...

一键分析Bulk转录组数据
我们前面介绍了经典的转录组分析流程:Hisat2 Stringtie,可以帮助用户快速获得基因的表达量矩阵。 云上生信,未来已来 | 转录组标准分析流程重磅上线! RNA STAR 也是一款非常流行的转录组数据分析工具。它不仅可以将测序 Reads 比…...

Django DetailView视图
Django的DetailView是一个用于显示单个对象详情的视图。下面是一个使用DetailView来显示单个书籍详情的例子。 1,添加视图 Test/app3/views.py from django.shortcuts import render# Create your views here. from django.views.generic import ListView from .m…...

openGauss学习笔记-300 openGauss AI特性-AI4DB数据库自治运维-DBMind的AI子功能-SQL Rewriter SQL语句改写
文章目录 openGauss学习笔记-300 openGauss AI特性-AI4DB数据库自治运维-DBMind的AI子功能-SQL Rewriter SQL语句改写300.1 概述300.2 使用指导300.2.1 前提条件300.2.2 使用方法示例300.3 获取帮助300.4 命令参考300.5 常见问题处理openGauss学习笔记-300 openGauss AI特性-AI…...
typescript-泛型
typescript-泛型 泛型程序设计是一种编程风格或编程范式,允许在程序中定义形式类型参数,然后再泛型实例化时候使用实际类型参数来替代形式类型参数,通过泛型,可以定义通用的数据结构或类型,这种数据结构或类型仅仅再它…...

应急响应 | 基本技能 | 01-系统排查
系统排查 目录 系统基本信息 Windows系统Linux系统 用户信息 Windows系统 1、命令行方式2、图形界面方法3、注册表方法4、wmic方法 Linux系统 查看所有用户信息分析超级权限账户查看可登录的用户查看用户错误的登录信息查看所有用户最后的登录信息查看用户最近登录信息查看当…...

用c语言实现通讯录
目录 静态简易通讯录 代码: 功能模块展示: 设计思路: 动态简易通讯录(本质顺序表) 代码: 扩容模块展示: 设计思路: 文件版本通讯录 代码: 文件模块展示&#x…...

AI大模型技术揭秘-参数,Token,上下文和温度
深入理解 AI 大模型:参数、Token、上下文窗口、上下文长度和温度 人工智能技术的飞速发展使AI大模型大放异彩,其中涉及的“参数”、“Token”、“上下文窗口”、“上下文长度”及“温度”等专业术语备受瞩目。这些术语背后究竟蕴含何意?它们如何影响AI大模型的性能?一起揭开…...

攻防世界-fakebook题目__详解
1.打开题目先用dirsearch工具扫描一波,扫出来了robots.php目录,然后访问robots.txt 目录,发现了有一个备份文件 ,访问备份文件,下载内容 文件的大致内容如下 里面有一个curl_exec这个函数容易造成ssrf攻击的漏洞 我…...

Ubuntu 18.04下普通用户的一次提权过程
Ubuntu 18.04下普通用户的一次提权过程 一.背景介绍:二.主要调试过程:三.相关命令:1.设置BMC密码,获取BMC IP2.找一台ubuntu搭建TFTP服务,用来替换grub.cfg文件3.从调试服务器的/boot/grub/grub.cfg中提取出recovery mode的配置,简化并生成新的配置文件grub.cfg,放在tftp服务的…...
接口和抽象类:如何使用普通类模拟接口和抽象类
目录 1.引言 2.抽象类和接口的定义与区别 3.抽象类和接口存在的意义 4.模拟实现抽象类和接口 5.抽象类和接口的应用场景 1.引言 在面向对象编程中,抽象类和接口是两个经常被提及的语法概念,也是面向对象编程的四大特性,以及很多设计模式…...

【文档智能】实践:基于Yolo三行代码极简的训练一个版式分析模型
一、数据集 本文以开源的CDLA数据集做为实验,CDLA是一个中文文档版面分析数据集,面向中文文献类(论文)场景。包含以下10个label: 数据集下载地址:https://github.com/buptlihang/CDLA 数据集是labelme格式…...

聚观早报 | 深蓝G318价格发布;比亚迪方程豹豹3官图发布
聚观早报每日整理最值得关注的行业重点事件,帮助大家及时了解最新行业动态,每日读报,就读聚观365资讯简报。 整理丨Cutie 6月15日消息 深蓝G318价格发布 比亚迪方程豹豹3官图发布 夸克App升级高考AI搜索 iOS 18卫星通信实测 Redmi K70…...
如何实现内网穿透?快解析-免费内网穿透工具
在现如今的ipv4时代,随着上网电脑及其他智能设备越来越多,公网IP地址出现了枯竭的情况。近几年,内网穿透这个词被不断提及,这也是在无公网IP环境下实现异地访问的一种可行办法,下面我就给大家介绍一下内网穿透的原理。…...

【python-AI篇】人工智能技能树思维导图
大致总结一下得出如下思维导图,如不完善日后迭代更新 1. python基础三方库 1.1 科学计算库 ---- numpy库 1.2 科学计算库 ---- Scipy库 1.3 数据分析处理库 ---- pandas库 1.4 可视化库 ---- matplotlib库 1.5 可视化库 ---- seaborn库 1.6 机器学习和数据挖掘库 …...
Vue的computed大致细节
computed computed具体实现流程computer的执行顺序 computed 具体实现流程 computer内部首先是标准化参数然后调用runner函数进行依赖收集设置dirty为true创建副作用函数,具体如下 const runner effect(getter,{//延迟执行lazy:true,//标记为computed effect 用…...
第5章:模型预测控制(MPC)的代码实现
1. 建立 QP 模型: 1.1 车辆模型: 注:使用车辆横向动力学模型 纵向动力学模型(误差模型) 1.2 QP 问题模型: 注:详细推导见 笔记100:使用 OSQP-Eigen 对 MPC 进行求解的方法与代码-…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

10-Oracle 23 ai Vector Search 概述和参数
一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...

GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...

车载诊断架构 --- ZEVonUDS(J1979-3)简介第一篇
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...