工厂模式(二):工厂方法模式
一、概念
工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。从而使得系统更加灵活。客户端可以通过调用工厂方法来创建所需的产品,而不必关心具体的实现细节。这种模式符合开放-封闭原则,对扩展开放、对修改关闭。
二、与简单工厂模式的区别
特点 | 简单工厂 | 工厂方法模式 |
---|---|---|
定义 | 由一个工厂类负责创建所有产品对象。 | 定义一个用于创建对象的接口,让子类决定实例化哪一个类。 |
角色数量 | 只有一个工厂类,可能会有多个产品类。 | 有多个具体工厂类,每个具体工厂负责创建一种产品。 |
扩展性 | 添加新产品时需要修改简单工厂类,违反开闭原则。 | 添加新产品只需增加新的具体工厂和产品类,不需要修改现有代码。 |
客户端代码 | 客户端直接依赖于简单工厂类,通常需要知道具体的产品类型。 | 客户端只依赖于抽象工厂类,不需要知道具体的工厂实现。 |
复杂度 | 实现较为简单,适合产品较少的情况。 | 实现较为复杂,但适合需要扩展的系统。 |
如图我们在简单工厂模式中计算器的例子,如果我在新增一个计算方法√、或者平方、立方那么我将直接改造工厂类,如果新增的许多计算方法,那么我们简单工厂中将会有大量的代码逻辑,这违反了开闭原则的。
在比如我们想买一辆比亚迪电车,最初比亚迪比较小,只有一个工厂,我们所有的车都在这个工厂里制造没问题,可随着比亚迪的发展越来越牛逼,不仅有低端车更是有几百万的高端车,这时候一个工厂远远满足不了产能的需求,而且如果这个工厂gg了,所有的车都制造不出来了,这是不被允许的,于是领导小手一拍建立了多个不同车型的制造工厂,比如王朝系列,海洋系列工厂,分别制造不同的车型,这就是从简单工厂模式->工厂方法模式的进阶。
优点
- 遵循开闭原则:可以通过添加新的具体工厂和产品类来扩展产品,而无需修改现有代码,增强了系统的可扩展性。提高代码灵活性:
- 客户端只依赖于抽象工厂接口,具体产品的创建逻辑在子类中实现,客户端无需了解具体实现。
- 封装对象创建:将对象的创建过程封装在工厂子类中,客户端代码更加简洁,关注于使用而不是创建。
- 减少耦合将产品的实例化与使用分离,不需要知道每个具体产品的类名,降低了系统的耦合度。
缺点
- 增加代码复杂性:引入多个工厂和产品类,代码结构较为复杂,对于简单需求可能显得过于臃肿。
- 类数量增多:每增加一种新产品都需要相应地增加一个具体工厂类,这可能导致系统中类的数量增加,管理起来较为繁琐。
- 学习成本:对于不熟悉设计模式的开发者来说,理解和正确应用工厂方法模式需要一定时间和经验。
三、适用场景
当一个类不知道它所必须创建的对象的类时。
当一个类希望由其子类来指定生成对象时。
当将创建对象的职责委托给多个帮助子类中的某一个,并希望将哪一个子类是代理者这一信息局部化时。
通过合理使用工厂方法模式,可以提升系统的灵活性和可维护性,但需要权衡其复杂性和实际需求。
四、实例分析
接着上述计算器的例子,我们继续优化。
对于加减乘除这种很基础的操作我们可以单独封装为基础运算操作类,对于根号运算,幂等运算可以定义为高级运算操作类,这样无论我添加多少额外的运算方法,都不会影响基础的运算。
先定义一个用于创建对象的接口,定义了一个创建 Operation对象的方法 createOperation()。这个方法没有具体的实现,而是留给子类来决定如何创建具体的对象。
增加两个高级运算类 指数运算、对数运算。
具体工厂类 FactoryBasic 和 FactoryAdvanced 继承自 IFactory,并实现了 createOperation() 方法。在这些子类中,具体的实例化逻辑被定义为返回对应运算方法的运算对象。
对比与简单工厂方法中的OperationFactory,新的OperationFactory类已经不存在运算子类实例化的
代码了。也就是说,在这个代码里,全部是接口与具体工厂类,并不存在具体的实现,与原来的OperationFactory类对比,实例化的过程延迟到了工厂子类中。
相关文章:

工厂模式(二):工厂方法模式
一、概念 工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。从而使得系统更加灵活。客户端可以通过调用工厂方法来创建所需的产品,而不必…...
【洛谷】P11036 【MX-X3-T3】「RiOI-4」GCD 与 LCM 问题 的题解
【洛谷】P11036 【MX-X3-T3】「RiOI-4」GCD 与 LCM 问题 的题解 题目传送门 题解 神奇构造题qaq 简化一下下题目,就是要求 a b c d gcd ( a , b ) lcm ( c , d ) a b c d \gcd(a, b) \operatorname{lcm}(c,d) abcdgcd(a,b)lcm(c,d) 分类讨论 …...
MyBatis系统学习(三)——动态SQL
MyBatis 是一款优秀的持久层框架,它通过 XML 或注解方式将 SQL 语句与 Java 对象映射起来。动态 SQL 是 MyBatis 中非常强大的功能之一,能够根据不同的条件动态生成 SQL 语句。动态 SQL 通过各种标签来灵活生成 SQL,从而避免了在代码中拼接 S…...
get_property --Cmakelist之中
get_property 是 CMake 中用于获取目标、目录、变量或文件等属性的命令。它可以提取某个特定属性的值,以便在构建脚本的其他地方使用。 语法 get_property(<variable> <TYPE> <name> PROPERTY <property-name> [SET | DEFINED | BRIEF_DO…...

【Redis】Redis 典型应用 - 分布式锁原理与实现
目录 Redis 典型应⽤ - 分布式锁什么是分布式锁分布式锁的基础实现引⼊过期时间引⼊校验 id引⼊ lua引⼊ watch dog (看⻔狗)引⼊ Redlock 算法其他功能 Redis 典型应⽤ - 分布式锁 什么是分布式锁 在⼀个分布式的系统中, 也会涉及到多个节点访问同⼀个公共资源的…...
Pybind11的使用
目录 1. 引言1.1 Pybind11 简介1.2 为什么需要 Pybind11 2. 使用 Pybind11 进行 C 与 Python 交互2.1 基本用法2.2 编译与生成共享库2.2.1 在 Linux 下编译2.2.2 在 macOS 下编译2.2.3 编译选项详解 2.3 在 Python 中使用编译后的模块 3. 高级用法与注意事项3.1 绑定类和复杂数…...
鸿蒙-沉浸式pc端失效
咨询描述: 因PC北向窗口涉及沉浸式时,预计发生接口废弃导致不兼容变更,涉及接口setImmersiveModeEnabledState、setWindowLayoutFullSceen 如果应用支持沉浸式(窗口全屏且隐藏状态栏&标题栏&Dock栏)࿰…...

【资料分析】刷题日记1
第一套 第二个是相比2019年的增长率,错找为同比增长率 延申: 当出口和进口相比2019年的增长率相同时,可以用盐水解决 √ 一个假设分配(第二次是1.4取1)加法对比选项 基期倍数: 求A是B的多少倍&#x…...

nodejs+express+vue教辅课程辅助教学系统 43x2u前后端分离项目
目录 技术栈具体实现截图系统设计思路技术可行性nodejs类核心代码部分展示可行性论证研究方法解决的思路Express框架介绍源码获取/联系我 技术栈 该系统将采用B/S结构模式,开发软件有很多种可以用,本次开发用到的软件是vscode,用到的数据库是…...
96-javahashmap底层原理
HashMap是Java集合框架中的一个重要类,底层是基于哈希表实现的。哈希表是一种数据结构,可以通过哈希函数来提高查找、插入和删除操作的效率。 以下是HashMap底层实现的一些关键点: 哈希算法:HashMap使用哈希算法来计算键的哈希值…...

AI逻辑推理入门
参考数据鲸 (linklearner.com) 1. 跑通baseline 报名 申领大模型API 模型服务灵积-API-KEY管理 (aliyun.com) 跑通代码 在anaconda新建名为“LLM”的环境,并安装好相应包后,在jupyter notebook上运行baseline01.ipynb 2. 赛题解读 一般情况下,拿到一个赛题之后,我们需…...
力扣3014.输入单词需要的最少按键次数I
给你一个字符串 word,由 不同 小写英文字母组成。 电话键盘上的按键与 不同 小写英文字母集合相映射,可以通过按压按键来组成单词。例如,按键 2 对应 ["a","b","c"],我们需要按一次键来输入 "…...

【Git】远程仓库
本博客的环境是 Ubuntu/Linux 文章目录 集中式与分布式的区别远程仓库新建远程仓库克隆远程仓库向远程仓库推送从远程仓库拉取 配置Git忽略指定文件给命令配置别名 标签管理创建标签操作标签 多人协作本地分支与远程分支连接场景一场景二 集中式与分布式的区别 引荐自关于Git这…...

苹果手机铃声怎么设置自己的歌?3个方法自定义手机铃声
苹果手机内部的手机铃声库只有固定的几首铃声,且都是纯音乐,比较单调,并不是所有用户都喜欢这些铃声。那么,苹果手机铃声怎么设置自己的歌呢?小编这里有3个方法,可以教大家如何将手机铃声设置成自己喜欢的歌…...

828华为云征文|华为Flexus云服务器搭建Cloudreve私人网盘
一、华为云 Flexus X 实例:开启高效云服务新篇🌟 在云计算的广阔领域中,资源的灵活配置与卓越性能犹如璀璨星辰般闪耀。华为云 Flexus X 实例恰似一颗最为耀眼的新星,将云服务器技术推向了崭新的高度。 华为云 Flexus X 实例基于…...
【AI学习】AI绘画发展简史
无意中读了一篇发表自2022年的文章,《AI绘画何以突飞猛进? 从历史到技术突破, 一文读懂火爆的AI绘画发展史》,写的比较有意思,科普了好多我原来不知道的历史。 简单提炼一下,做个笔记。 AI绘画重要事件 2012年 Google两位大名…...
使用LangChain创建简单的语言模型应用程序【快速入门指南】
## 引言在这篇文章中,我们将展示如何使用LangChain构建一个简单的语言模型(LLM)应用程序。这个应用程序的功能是将文本从英语翻译成其他语言。尽管应用程序的逻辑相对简单,但它能够帮助我们学习如何使用LangChain进行更多复杂的功…...

嵌入式人工智能项目及人工智能应用项目——大合集列表查阅
本文的项目合集列表可能更新不及时(会及时更新),可查阅实时更新的链接如下。 嵌入式人工智能及人工智能应用项目合集实时更新链接如下: 阿齐嵌入式人工智能及人工智能应用项目合集 (kdocs.cn)https://www.kdocs.cn/l/cc97tuieys4…...

心觉:成功学就像一把刀,有什么作用关键在于使用者(一)
Hi,我是心觉,与你一起玩转潜意识、脑波音乐和吸引力法则,轻松掌控自己的人生! 挑战每日一省写作173/1000天 很多人觉得成功学是鸡汤,是没用的,甚至是骗人的 我先保持中立,不知道对不对 我们先…...

GAMES101(10节,几何)
Geometry implicit隐式几何表示: 函数f(x,y,z): 根据函数fn描述几何,遍历所有空间内 的点,如果带入xyz到函数f(x,y,z)结果0那就绘制这个点 如果xyz求值结果>0表示在几何外,0在表面,<0在几何内 构造几何csg(…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...