设计模式:简单工厂模式
工厂设计模式属于创建型模式,它提供了一种创建对象的最佳方式。工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。工厂模式属于创建型模式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。
面相对象编程中,万物皆对象。每个对象如果都通过关键字new创建,则会导致对象与其调用者耦合严重。假如更换要new的对象,则所有new对象的地方都需要改变代码,这显然违背了“开-闭原则”。如果使用工厂来生产对象,我们只需要和工厂打交道,彻底和对象解耦,如果更换对象,只需要在工厂里更换对象,而不需要再所有的地方进行更换,这样达到了与对象解耦的目的。工厂模式最大优点就是解耦。
简单工厂模式
简单工厂模式根据传入的参数,决定创建哪个类型的实例。简单工厂模式本着高内聚低耦合的原则,将系统的逻辑部分和功能分开。
使用场景
首先当然是在你需要new一个类的对象的时候,此时各种状况出现啦:
- 你不想直接new这个类的对象,怕以后这个类改变的时候你需要回来改代码,而此时依赖这个类的地方已经到处都是了。
- 这个类的对象构建过程非常复杂,你不愿意将这么复杂的构建过程一遍又一遍的写在需要用到此对象的地方。
- 这个类的对象在构建过程中依赖了很多其他的类,而你无法在调用的地方提供
- JDK源码中的 Calendar.getInstance()方法。
- Logback源码中多个重载的 getLogger()方法。
-
QQ 换皮肤,一整套一起换。
-
生成不同操作系统的程序。
简单工厂模式的3个角色:
- 对象工厂(SimpleFactory),负责实现创建所有产品实例的内部逻辑。
- 抽象产品,即要生产的对象的接口,描述所有实例要实现的公共接口。
- 具体产品,即创建的产品实例。所有创建的实例都是抽象产品的具体实现。
结构图:

优缺点
优点:
- 结构简单,调用方便。工厂和产品的职责区分明确。
- 客户端无需知道所创建具体产品的类名,只需知道参数即可。
缺点:
- 简单工厂模式的工厂类单一,负责所有产品的创建,职责过重,一旦异常,整个系统将受影响。
- 违背“开放-关闭原则”,一旦添加新产品就必须修改简单工厂类的内部逻辑,工厂类代码会非常臃肿,违背高聚合原则。
- 简单工厂模式使用了静态工厂方法,静态方法不能被继承和重写,造成工厂角色无法形成基于继承的等级结构。
应用实例:
简易计算器为例,需求:输入两个数和运算符,得到结果。
抽象产品:
public abstract class Operation {protected abstract double compute (double number1, double number2) throws Exception;
}
具体产品:
// 加法
public class OperationAdd extends Operation{@Overrideprotected double compute(double number1, double number2) {return number1 + number2;}
}// 减法
public class OperationSub extends Operation{@Overrideprotected double compute(double number1, double number2) {return number1 - number2;}
}// 乘法
public class OperationMul extends Operation{@Overrideprotected double compute(double number1, double number2) {return number1 * number2;}
}// 除法
public class OperationDiv extends Operation{@Overrideprotected double compute(double number1, double number2) throws Exception {if(number2 == 0){throw new Exception("除数不能为0!");}return number1 / number2;}
}
对象工厂:
这里对简单工厂创建产品进行了优化,可以通过缓存、配置文件、反射和泛型等技术了优化。
如果运算业务需要扩展,需要创建具体运算类即可,不需要再修改简单工厂类了。
public class OperationFactory {private static final Map<String, Operation> cachedParsers = new HashMap<>();static {cachedParsers.put("+", new OperationAdd());cachedParsers.put("-", new OperationSub());cachedParsers.put("*", new OperationMul());cachedParsers.put("/", new OperationDiv());}public static Operation createOperate0(String operate) {if (operate == null || operate.isEmpty()) {return null;//返回null还是IllegalArgumentException全凭你自己说了算}return cachedParsers.get(operate);}/*** createOperate0运用缓存技术,节省内存和对象创建的时间* createOperate0 和 createOperate1 同理*/public static Operation createOperate1(String operate){Operation operation = null;switch (operate){case "+":operation = new OperationAdd(); break;case "-":operation = new OperationSub(); break;case "*":operation = new OperationMul(); break;case "/":operation = new OperationDiv(); break;}return operation;}/*** createOperate1方法不符合开闭原则* 如果运算业务继续扩展,需要创建具体运算类,也需要修改简单工厂的 createOperate1方法。* 采用反射技术进行优化,即createOperate2方法*/public static Operation createOperate2(String className){Operation operation = null;try {if(!(null == className || "".equals(className))){operation = (Operation) Class.forName(className).newInstance();}} catch (Exception e) {e.printStackTrace();}return operation;}/*** createOperate2方法中类型强制转型,参数为字符串,可控性不高* 采用反射和泛型技术进行优化,即createOperate3方法*/public static Operation createOperate3(Class<? extends Operation> clazz){try {if(null != clazz){return clazz.newInstance();}} catch (Exception e) {e.printStackTrace();}return null;}}
测试:
public class Test {public static void main(String[] args) throws Exception {double num1 = 10;double num2 = 2;System.out.println(OperationFactory.createOperate0("*").compute(num1, num2));System.out.println(OperationFactory.createOperate1("*").compute(num1, num2));Operation operate2 = OperationFactory.createOperate2("cn.jq.learn.simplefactorypattern.OperationDiv");System.out.println(operate2.compute(num1, num2));Operation operate3 = OperationFactory.createOperate3(OperationAdd.class);System.out.println(operate3.compute(num1, num2));}
}
相关文章:
设计模式:简单工厂模式
工厂设计模式属于创建型模式,它提供了一种创建对象的最佳方式。工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。工厂模式属于创建型模式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离。 …...
老龄化对投资意味着什么?
1月15日,国务院办公厅印发《关于发展银发经济增进老年人福祉的意见》从4个方面提出26项举措,为我国首个以“银发经济”命名的政策文件。 近期,国信证券分析师王开发布题为《银发经济再思考:老龄化对投资的影响》的报告࿰…...
从公有云对象存储迁移到回私有化 MinIO需要了解的所有信息
我们上一篇文章《如何从 AWS S3 遣返到 MinIO》的反响非常出色 - 我们已经接到了数十个企业的电话,要求我们提供遣返建议。我们已将这些回复汇总到这篇新文章中,其中我们更深入地研究了与遣返相关的成本和节省,以便您更轻松地进行自己的分析。…...
C#颜色拾取器
1,目的: 获取屏幕上任意位置像素的色值。 2,知识点: 热键的注册与注销。 /// <summary>/// 热键注册/// </summary>/// <param name"hWnd">要定义热键的窗口的句柄 </param>/// <param name"id…...
最长公共子串的问题(正常方法和矩阵法,动态规划)
题目: 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 ,返回 0 。 一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符…...
Linux实验记录:使用LVM(逻辑卷管理器)
前言: 本文是一篇关于Linux系统初学者的实验记录。 参考书籍:《Linux就该这么学》 实验环境: VmwareWorkStation 17——虚拟机软件 RedHatEnterpriseLinux[RHEL]8——红帽操作系统 备注: 硬盘分好区或者部署为RAID磁盘阵列…...
[设计模式Java实现附plantuml源码~创建型] 复杂对象的组装与创建——建造者模式
前言: 为什么之前写过Golang 版的设计模式,还在重新写Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很…...
【国产MCU】-认识CH32V307及开发环境搭建
认识CH32V307及开发环境搭建 文章目录 认识CH32V307及开发环境搭建1、CH32V307介绍2、开发环境搭建3、程序固件下载1、CH32V307介绍 CH32V307是沁恒推出的一款基于32位RISC-V设计的互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度…...
python flask request教程
request 一、传json1、resquest.get_data()与resquest.data2、request.get_json()3、request.json["imageURL"]二、传file1、request.files["file"]2、request.form["username"]3、request.form.get(username)与2等价,其他get()与[]也相同三、其…...
UE5 Chaos系统 学习笔记
记得开插件: 1、锚点场(构造场) 在锚点场范围内的物体静止且不被其他力场损坏 需要在Geometry Collection的初始化场把构造场设置过去 2、ClusterStrain 破裂效果的力 3、DisableField chaos破裂后的模拟物理在绿色范围内禁止行为和模拟物…...
MkDocs 部署指南
简介 MkDocs 可以同时编译多个 markdown 文件,形成书籍一样的文件。有多种主题供你选择,很适合项目使用。 MkDocs 是快速,简单和华丽的静态网站生成器,可以构建项目文档。文档源文件在 Markdown 编写,使用单个 YAML …...
【Java 设计模式】行为型之访问者模式
文章目录 1. 定义2. 应用场景3. 代码实现结语 访问者模式(Visitor Pattern)是一种行为型设计模式,用于在不改变被访问元素的类的前提下定义对这些元素的新操作。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可以灵…...
堆和堆排序【数据结构】
目录 一、堆1. 堆的存储定义2. 初始化堆3. 销毁堆4. 堆的插入向上调整算法 5. 堆的删除向下调整算法 6. 获取堆顶数据7. 获取堆的数据个数8. 堆的判空 二、Gif演示三、 堆排序1. 堆排序(1) 建大堆(2) 排序 2.Topk问题 四、完整代码1.堆的代码Heap.cHeap.htest.c 2. 堆排序的代码…...
【全程录屏GPT3.5升级4.0】2024最新GPT4升级订阅详细指南
前言:为什么要升级GPT4.0,下图是来自GPT4.0的官方回答,可以看出,GPT4无愧于是一个大版本升级的。 一、视频教程 记录了普通用户使用WildCrad从GPT3.5升级到4.0的全部过程,感兴趣可以前往观看:https://www.…...
中移(苏州)软件技术有限公司面试问题与解答(4)—— virtio所创建的设备1
接前一篇文章:中移(苏州)软件技术有限公司面试问题与解答(0)—— 面试感悟与问题记录 本文参考以下文章: VirtIO实现原理——PCI基础 VirtIO实现原理——virtblk设备初始化 特此致谢! 本文对…...
《动手学深度学习(PyTorch版)》笔记5
注:书中对代码的讲解并不详细,本文对很多细节做了详细注释。另外,书上的源代码是在Jupyter Notebook上运行的,较为分散,本文将代码集中起来,并加以完善,全部用vscode在python 3.9.18下测试通过,…...
QT中wchar_t类型如何输出
在Qt中,通常使用QString来处理字符串,而不是wchar_t。QString是Qt中用于处理Unicode字符串的类。如果你有wchar_t类型的字符串,你可以将其转换为QString进行输出。 以下是一个简单的例子: #include <QCoreApplication> #i…...
网络安全04-sql注入靶场第一关
目录 一、环境准备 1.1我们进入第一关也如图: 编辑 二、正式开始第一关讲述 2.1很明显它让我们在标签上输入一个ID,那我们就输入在链接后面加?id1 编辑 2.2链接后面加个单引号()查看返回的内容,127.0.0.1/sqli/less-1/?id1,id1 …...
微服务理解篇
一 :架构演变 1 单体架构: 简单理解为一个服务涵盖所有需求功能2 垂直架构: 按照业务功能将单体架构拆分成小模块服务, 如:订单系统,用户系统,商品系统 ##缺点 引入分布式事务,分布式锁等,优点:模块解耦## 垂直拆分:根据业务层级拆分,比如商城的订单系统,用户系统,商品系统…...
项目篇:基于TCP通信模型的外卖软件实现
一、基本成员及功能实现 本项目主要由服务器,消费者,商家,外卖员组成。基本的功能如下。 对所有人: 1、可以注册登录 2、可以修改个人信息 3、可以销户 商家: 1、注册时需要填写售卖商品信息 2、可以修改商品信…...
(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
golang循环变量捕获问题
在 Go 语言中,当在循环中启动协程(goroutine)时,如果在协程闭包中直接引用循环变量,可能会遇到一个常见的陷阱 - 循环变量捕获问题。让我详细解释一下: 问题背景 看这个代码片段: fo…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材)
推荐 github 项目:GeminiImageApp(图片生成方向,可以做一定的素材) 这个项目能干嘛? 使用 gemini 2.0 的 api 和 google 其他的 api 来做衍生处理 简化和优化了文生图和图生图的行为(我的最主要) 并且有一些目标检测和切割(我用不到) 视频和 imagefx 因为没 a…...
Golang——9、反射和文件操作
反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一:使用Read()读取文件2.3、方式二:bufio读取文件2.4、方式三:os.ReadFile读取2.5、写…...
