当前位置: 首页 > news >正文

Java进阶篇设计模式之二 ----- 工厂模式

前言

在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法。本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式、工厂方法和抽象工厂模式。

简单工厂模式

简单工厂模式是属于创建型模式,又叫做静态工厂方法模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。调用只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类工厂的子类。 可以说是工厂模式中最简单的一种。

打个比方,我们在电脑经常玩游戏,我们只需要告诉电脑我们要玩什么游戏,电脑就会打开这个游戏,我们并不需要关心游戏是怎么运作的。
我们可以在以下的代码中进行相应的说明。

我们首先创建一个游戏总类接口,包含一个玩游戏的方法; 然后再由各自的游戏类继承该类并实现该类的方法,最后在创建一个工程类根据不同的游戏进行创建对象。
那么实现的代码如下:

代码示例:

private static final String LOL="LOL"; private static final String DNF="DNF"; public static void main(String[] args) {Game game= ComputerFactory.playGame(LOL);Game game2= ComputerFactory.playGame(DNF);game.play();game2.play();}
}interface Game{void play();
}class LOL implements Game{@Overridepublic void play() {System.out.println("正在玩LOL...");}	
}class DNF implements Game{@Overridepublic void play() {System.out.println("正在玩DNF...");}	
}class ComputerFactory{private static final String LOL="LOL"; private static final String DNF="DNF"; public static Game playGame(String game){if(LOL.equalsIgnoreCase(game)){return new LOL();}else if(DNF.equalsIgnoreCase(game)){return new DNF();}return null;}	

输出结果:

正在玩LOL...
正在玩DNF...

我们在使用简单工厂模式进行实现该功能之后,会发现我们将游戏类的实例化放到了工厂类中实现,隐藏了对象创建的细节,并且不需要知道是怎么玩的,只需要知道调用该工厂类就行了。而且方便切换,因为只需更改工厂类传递的类型值就行了。
但是我们也发现一个问题,如果我们需要新增一个游戏类,那么需要新定义一个接口,然后还要在工厂类中添加一个判断分支,如果少量的话还好,但是大量的话就比较麻烦了,并且这也违背了开放-封闭原则。

工厂方法模式

工厂方法模式是 Java 中最常用的设计模式之一,属于创建型模式。定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

在简单工厂模式中,我们发现在添加子类的时候,相应的也需要在工厂类中添加一个判断分支,是违背了开放-封闭原则的。而工厂方法模式就是主要解决这个问题的。

这里还是用上述的玩游戏示例,只不过这里每个游戏都是由各自的游戏工厂类实现。主要区别就是由一个 工厂类变成了多个了,降低了耦合度。如果新增一个游戏类,相应的也只需在新增一个工厂类而已, 并且完美的遵循了开放-封闭原则。

将上述代码更改之后,相应的代码实现如下:

代码示例:

	private static final String LOL="LOL"; private static final String DNF="DNF"; private static final String WOW="WOW"; public static void main(String[] args) {Game game3=new LOLFactory().playGame();Game game4=new DNFFactory().playGame();Game game5=new WOWFactory().playGame();game3.play();game4.play();game5.play();		}interface Game{void play();
}class LOL implements Game{@Overridepublic void play() {System.out.println("正在玩LOL...");}	
}class DNF implements Game{@Overridepublic void play() {System.out.println("正在玩DNF...");}	
}class WOW  implements Game{@Overridepublic void play() {System.out.println("正在玩WOW...");}	
}interface ComputerFactory2{Game playGame(String game);
}class LOLFactory implements ComputerFactory2{@Overridepublic Game playGame() {return new LOL();}
}class DNFFactory implements ComputerFactory2{@Overridepublic Game playGame() {return new DNF();}
}class WOWFactory implements ComputerFactory2{@Overridepublic Game playGame() {return new WOW();}
}

输出结果:

正在玩LOL...
正在玩DNF...
正在玩WOW...

可以看到使用工厂方法模式之后,我们的代码更加清晰了,扩展性也变高了,如果想增加一个产品,只要扩展一个工厂类就可以。但是随之而来的是在系统中增加了复杂度,每增加一个产品时,都需要增加一个具体类和对象实现工厂类。
所以在是否使用该模式需注意。
使用该模式比较经典的使用案例是大名鼎鼎的hibernate框架在选择数据库方言这块。但是如果直接简单的new一个对象的话,则不必使用了,若使用反而会增加系统的复杂度。

抽象工厂模式

抽象工厂模式是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。也就是提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

抽象工厂模式相比工厂方法模式来说更加复杂,也更难理解,但是更容易扩展。
抽象工厂模式就将同一类的产品子类归为一类,让他们继承同一个抽象子类,然后把它们当作一组,然后再把多个组组成一个族。
打个比方,还是上述的玩游戏,我们可以把LOLWOW当作PVP类型的游戏,也可以把DNFWOW当作PVE类型的游戏。

那么相应更改的代码如下:

代码示例:

	private static final String LOL="LOL"; private static final String DNF="DNF"; private static final String WOW="WOW"; public static void main(String[] args) {ComputerFactory3 cf3=new PVPFactory();cf3.playGame().play();cf3.playGame2().play();ComputerFactory3 cf4=new PVEFactory();cf4.playGame().play();cf4.playGame2().play();			}		
}interface Game{void play();
}class LOL implements Game{@Overridepublic void play() {System.out.println("正在玩LOL...");}	
}class DNF implements Game{@Overridepublic void play() {System.out.println("正在玩DNF...");}	
}class WOW  implements Game{@Overridepublic void play() {System.out.println("正在玩WOW...");}	
}interface ComputerFactory3{Game playGame();Game playGame2();
}class PVPFactory implements ComputerFactory3{@Overridepublic Game playGame() {return new LOL();}@Overridepublic Game playGame2() {return new WOW();}	
}class PVEFactory implements ComputerFactory3{@Overridepublic Game playGame() {return new DNF();}@Overridepublic Game playGame2() {return new WOW();}}

输出结果:

正在玩LOL...
正在玩WOW...
正在玩DNF...
正在玩WOW...

在抽象工厂模式中,可以在不需要知道产品是怎么样的,只需知道是哪个工厂类就行了。我们也可以根据子类的共同的特性而将它们设计在一起,组成一个相同类型组,可以很方便的直接调用。但是相对的,产品族比较难以扩展,增加一个产品,需要增加相应的接口和实现类。例如某个品牌的手机,有不同系列,每个系列有不同的型号,如果只是增加型号的话,比较容易,但是相对的,增加某个系列就比较麻烦了。
所以我们在使用抽象工厂模式,也需要相应的结合实际场景来使用。

相关文章:

Java进阶篇设计模式之二 ----- 工厂模式

前言 在上一篇中我们学习了单例模式,介绍了单例模式创建的几种方法以及最优的方法。本篇则介绍设计模式中的工厂模式,主要分为简单工厂模式、工厂方法和抽象工厂模式。 简单工厂模式 简单工厂模式是属于创建型模式,又叫做静态工厂方法模式。…...

考研篇——数据结构王道3.2.2_队列的顺序实现

目录 1.实现方式说明2.代码实现2.12.1.1 代码12.1.2 代码22.1.3 代码3 2.22.2.1 代码42.2.5 代码52.2.6 代码6 总结 1.实现方式说明 多在选择题中考察 队尾指针(rear)有两种指向方式: 队尾指针指向队尾元素的位置,队尾指针指向…...

从零开始理解 Trie 树:高效字符串存储与查找的利器【自动补全、拼写检查】

题目分析 这道题让我们实现一个 Trie 类(也称为前缀树),以便高效地插入和查询字符串。前缀树是一种特殊的树形数据结构,适用于快速存储和检索字符串数据集中的键,比如实现 自动补全 和 拼写检查。 题目要求 Trie 类…...

关于sse、websocket与流式渲染

一、SSE是什么? 网络中的 SSE (Server-Sent Events) 是一种服务器向浏览器单向推送数据的机制,常用于需要实时更新的数据传输,如新闻推送、股票行情、聊天应用等。 SSE 的特点: 单向通信:服务器向客户端推送数据&…...

Python 语法与数据类型详解

Python 语法与数据类型详解 Python 以其简洁易读的语法和丰富多样的数据类型在编程领域占据重要地位。深入理解 Python 的语法和数据类型是掌握这门语言的关键。 一、Python 语法概述 (一)缩进规则 Python 独特的缩进规则是其语法的重要特征之一。与…...

LeetCode题练习与总结:扁平化嵌套列表迭代器--341

一、题目描述 给你一个嵌套的整数列表 nestedList 。每个元素要么是一个整数,要么是一个列表;该列表的元素也可能是整数或者是其他列表。请你实现一个迭代器将其扁平化,使之能够遍历这个列表中的所有整数。 实现扁平迭代器类 NestedIterato…...

51单片机快速入门之 AD(模数) DA(数模) 转换 2024/10/25

51单片机快速入门之 AD(模数) DA(数模) 转换 2024/10/25 声明:本文图片来源于网络 A模拟信号特点: 电压或者电流 缓慢上升 随着时间连续缓慢上升或下降 D数字信号特点:电压或者电流 保持一段时间的高/低电平 状态 / 突变 (高电压瞬间低电压) 数字电路中 通常将0-1v电压称…...

Typora 、 Minio and PicGo 图床搭建

流程介绍 本地安装Typora笔记工具拥有一台装有docker的服务器配置minio云图床管理控制页面下载PicGo上传工具服务器Docker环境搭建—Ubuntu系统 删除旧docker的所有依赖(非root用户) # 删除docker及安装时自动安装的所有包 sudo apt-get autoremove docker docker-ce docker…...

【计网】UDP Echo Server与Client实战:从零开始构建简单通信回显程序

目录 前言: 1.实现udpserver类 1.1.创建udp socket 套接字 --- 必须要做的 socket()讲解 代码实现:​编辑 代码讲解: 1.2.填充sockaddr_in结构 代码实现: 代码解析: 1.3.bind sockfd和…...

微服务网关Zuul

一、Zuul简介 Zuul是Netflix开源的微服务网关,包含对请求的路由和过滤两个主要功能。 1)路由功能:负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。 2)过滤功能:负责对请求的过程…...

BuildCTF线上赛WP

Build::CTF flag不到啊战队--WP 萌新战队,还请多多指教~ 目录 Build::CTF flag不到啊战队--WP Web ez!http find-the-id Pwn 我要成为沙威玛传奇 Misc what is this? 一念愚即般若绝,一念智即般若生 别真给我开盒了哥 四妹,你听…...

《使用Gin框架构建分布式应用》阅读笔记:p143-p207

《用Gin框架构建分布式应用》学习第10天,p143-p207总结,总计65页。 一、技术总结 1.auth0 本人实际工作中未遇到过,mark一下,参考:https://auth0.com/。 2.使用template (1)c.File() (2)router.Static() (3)rou…...

华为网络管理配置实例

目录 组网需求 数据规划 配置思路 操作步骤 结果验证 配置脚本 管理员可以通过eSight网管系统对FW进行监控和管理,接收FW的告警。 组网需求 如图1所示,某企业在网络边界处部署了FW作为安全网关,并部署了eSight网管系统对网络设备进行集中…...

大语言模型数据处理方法(基于llama模型)

文章目录 前言一、基于huggingface的DataCollatorForSeq2Seq方法解读1、DataCollatorForSeq2Seq方法2、batch最长序列填充3、指定长度填充二、构建大语言模型数据加工模块1、数据读取2、数据加工1、数据格式2、预训练(pretrain)数据加工3、微调(sft)数据加工①、sft数据加工…...

爱奇艺大数据多 AZ 统一调度架构

01# 导语 爱奇艺大数据技术广泛应用于运营决策、用户增长、广告分发、视频推荐、搜索、会员营销等场景,为公司的业务增长和用户体验提供了重要的数据驱动引擎。 多年来,随着公司业务的发展,爱奇艺大数据平台已积累了海量数据,这…...

【C++篇】栈的层叠与队列的流动:在 STL 的韵律中探寻数据结构的优雅之舞

文章目录 C 栈与队列详解:基础与进阶应用前言第一章:栈的介绍与使用1.1 栈的介绍1.2 栈的使用1.2.1 最小栈1.2.2 示例与输出 1.3 栈的模拟实现 第二章:队列的介绍与使用2.1 队列的介绍2.2 队列的使用2.2.1 示例与输出 2.3 队列的模拟实现2.3.…...

使用 Flask 实现简单的登录注册功能

目录 1. 引言 2. 环境准备 3. 数据库设置 4. Flask 应用基本配置 5. 实现用户注册 6. 实现用户登录 7. 路由配置 8. 创建前端页面 9. 结论 1. 引言 在这篇文章中,我们将使用 Flask 框架创建一个简单的登录和注册系统。Flask 是一个轻量级的 Python Web 框架…...

计算机毕业设计Python+大模型微博情感分析 微博舆情预测 微博爬虫 微博大数据 舆情分析系统 大数据毕业设计 NLP文本分类 机器学习 深度学习 AI

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 《Python大模型微博情感分析…...

CTF--Misc题型小结

(萌新笔记,多多关照,不足之处请及时提出。) 不定时更新~ 目录 密码学相关 文件类型判断 file命令 文件头类型 strings读取 隐写术 尺寸修改 文件头等缺失 EXIF隐写 thumbnail 隐写 文件分离&提取 binwalk foremo…...

深度学习系列——RNN/LSTM/GRU,seq2seq/attention机制

1、RNN/LSTM/GRU可参考: https://zhuanlan.zhihu.com/p/636756912 (1)对于这里面RNN的表示中,使用了输入x和h的拼接描述,其他公式中也是如此 (2)各符号图含义如下 2、关于RNN细节,…...

通过call指令来学习指令摘要表的细节

E8 cw cw 表示E8后面跟随2 字节 (什么数不知道) rel16 指在与指令同一代码段内的相对地址偏移 D ,指向Instruction Operand Encoding 表中的D列, 他告诉我们 操作数1 是一个0FFSET N.S. 在64位模式下,某些指令需要使用“地址覆盖前缀”(address over…...

10分钟使用Strapi(无头CMS)生成基于Node.js的API接口,告别繁琐开发,保姆级教程,持续更新中。

一、什么是Strapi? Strapi 是一个开源的无头(headless) CMS,开发者可以自由选择他们喜欢的开发工具和框架,内容编辑人员使用自有的应用程序来管理和分发他们的内容。得益于插件系统,Strapi 是一个灵活的 C…...

创建插件 DLL 项目

Step 1: 创建插件 DLL 项目 在 Visual Studio 中创建一个新的 DLL 项目&#xff0c;并添加以下文件和代码。 头文件&#xff1a;CShapeBase.h cpp 复制代码 #pragma once #include <afxwin.h> // MFC 必需头文件 #include <string> #include <vector> #i…...

OpenCV双目相机外参标定C++

基于OpenCV库实现双目测量系统外参标定过程。通过分析双目测量系统左右相机拍摄的棋盘格标定板图像&#xff0c;包括角点检测、立体标定、立体校正和畸变校正的步骤&#xff0c;获取左右相机的相对位置关系和姿态。 a.检测每张图像中的棋盘格角点&#xff0c;并进行亚像素级精…...

【GESP】C++一级练习BCQM3055,4位数间隔输出

一级知识点取余、整除运算和格式化输出知识点应用。其实也可以用string去处理&#xff0c;那就属于GESP三级的知识点范畴了&#xff0c;孩子暂未涉及。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3055/ https://www.coderli.com/gesp-1-bcqm3055/https://w…...

纯血鸿蒙的最难时刻才开始

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 纯血鸿蒙(HarmonyOS NEXT)也正式发布了&#xff0c;绝对是一个历史性时刻&#xff0c;但最难的鸿蒙第二个阶段&#xff0c;也就是生态圈的建设&#xff0c;才刚刚开始。 目前&#xff0c;我劝你现在不要升级到鸿蒙…...

记一个mysql的坑

数据库表user&#xff0c; 存在一个name字段&#xff0c;字段为varchar类型 现在user表有这么两条记录: idnameageclass1NULL18一班2lisi20二班 假如我根据下面这一条件去更新&#xff0c;更新成功数据行显示为0 update user set age 19 where age 18 and class “一班”…...

Java中的设计模式:单例模式详解

摘要 单例模式&#xff08;Singleton Pattern&#xff09;是Java中最常用的设计模式之一&#xff0c;属于创建型模式。它的主要目的是确保一个类在系统中只有一个实例&#xff0c;并提供一个全局访问点来访问该实例。 1. 单例模式的定义 单例模式确保一个类只有一个实例&…...

NanoTrack原理与转tensorrt推理

文章目录 前言一、NanoTrack 工作原理二、运行demo与转换tensorrt模型2.1 运行pt模型demo2.2 转onnx模型2.3 转tensorrt模型2.4 运行trt模型推理 三、推理速度对比总结 前言 NanoTrack 是一种轻量级且高效的目标跟踪算法&#xff0c;基于Siamese网络架构&#xff0c;旨在在资源…...

YOLO11改进 | 卷积模块 | 卷积模块替换为选择性内核SKConv【附完整代码一键运行】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 本文给大家带来的教程是将YOLO11的卷积替…...

湖南建设资质申请网站/谷歌下载官方正版

让我们通过使用TypeScript来构建一个简单的Web应用程序来入门吧 安装 TypeScript 获取TypeScript主要有两种方法&#xff1a; 通过npm &#xff08;Node.js包管理器&#xff09;通过安装Visual Studio TypeScript插件Visual Studio 2017和VIsual Studio 2015 Update 3 默认包含…...

南宁高端网站建设公司/东莞寮步最新通知

?点 Stephen 关 注 我 这是 Stephen 的第 76 篇原创文章哈喽&#xff0c;大家好&#xff0c;我是 Stephen&#xff0c;一个毕业三年后自学 Java 编程入行的程序员。我们知道松哥的 “微人事” 开源项目后面引入了 RabbitMQ 消息中间件。今天我们来一起学习 Windows 环境下 Ra…...

邪恶东做图网站/竞价托管推广公司

目录 增加产品审批流程 在字典里增加此产品 增加对应的人员审批节点 测试 增加产品审批流程 首先从已有的产品审批类型中复制出新产品的审批类型 insert into SYSStatus (PageName,CompanyId,Pro...

衡器行业网站建设模板/深圳市住房和建设局

2019独角兽企业重金招聘Python工程师标准>>> 前言 自己主要是IOS&#xff0c;但是也想业余时间学学后台的一点&#xff0c;之前用过mfc&#xff0c;c#,写点嵌入式辅佐小工具&#xff0c;现在入坑脱做IOS.所以&#xff0c;想向全栈走&#xff0c;就业余时间看看sprin…...

wordpress菜单图标插件/百度今日数据统计

编者按&#xff1a;目前虚拟化技术已经突破虚拟内存和虚拟服务器两大空间&#xff0c;延伸到网络虚拟化、微处理器虚拟化、文件虚拟化和存储虚拟化等许多领域。越来越多的企业也已经在内部采用虚拟化技术&#xff0c;那么企业实现虚拟化环境都有哪些优势呢&#xff1f; 尽管现如…...

柳北网站制作/网站功能优化

Microsoft Visual Studio 2010 的项目为件改为Microsoft Visual Studio 2015默认打开 2010 的Solution (.Sln) file Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 --默认打开的版本IDE Geovin Du 涂聚文 注释 Project("{FAE04EC…...