12 设计模式之工厂方法模式
一、什么是工厂方法模式?
1.定义
在软件开发中,设计模式 是解决常见软件设计问题的最佳实践。而 工厂方法模式(Factory Method Pattern) 作为创建型设计模式之一,常常被用来解决对象创建问题。它通过将对象的创建交给子类来解耦代码,使得代码更具灵活性与扩展性。
工厂方法模式定义了一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法让一个类的实例化推迟到其子类。这种模式常用于类的实例化逻辑非常复杂,或者需要提供多种类型的实例,而又不希望让客户端代码直接接触到具体类的实现时。
2.工厂方法模式的结构
- Product(产品接口):声明所有具体产品类需要实现的接口。
- ConcreteProduct(具体产品类):实现
Product接口的具体类。 - Creator(创建者类):声明工厂方法,通常是抽象类或接口,用于创建
Product对象。 - ConcreteCreator(具体创建者类):实现
Creator类,返回具体的ConcreteProduct对象。
3.工厂方法模式的优缺点
优点:
- 解耦:工厂方法模式将产品的创建和使用分离,避免了客户端程序与具体产品类的紧密耦合。
- 易扩展:新增产品类时,只需增加新的具体工厂类,客户端不需要修改,符合开闭原则。
- 封装复杂性:创建对象的过程可以被封装在工厂中,客户端无需关心创建过程的细节。
缺点:
- 增加代码量:每增加一个具体产品,都需要相应的具体工厂类,这会导致类的数量增多。
- 客户端调用不方便:如果产品种类很多,工厂类会增多,客户端代码可能会变得复杂。
二、图形工厂示例
为了更好地理解工厂方法模式,我们通过一个简单的图形绘制的例子来练习实现工厂方法模式。
1. 需求分析
我们需要设计一个图形绘制程序,支持绘制多种类型的图形(如圆形、三角形等)。每种图形的创建逻辑不同,为了将图形的创建过程与客户端代码解耦,我们决定使用工厂方法模式。
2. 设计类结构
- Shape接口:声明所有图形的绘制方法。
- 具体图形类:如
Circle、Triangle等,实现Shape接口,定义图形的绘制行为。 - 抽象工厂类
ShapeFactory:声明工厂方法createShape(),用于创建图形。 - 具体工厂类:如
CircleFactory和TriangleFactory,实现工厂方法并返回对应的图形对象。
3. 实现代码
以下是我们实现的代码:
// 图形接口
public interface Shape {void draw();
}// 圆形类
public class Circle implements Shape {@Overridepublic void draw() {System.out.println("画了一个圆");}
}// 三角形类
public class Triangle implements Shape {@Overridepublic void draw() {System.out.println("画了一个三角形");}
}// 抽象工厂类
public abstract class ShapeFactory {public abstract Shape createShape(); // 工厂方法
}// 圆形工厂
public class CircleFactory extends ShapeFactory {@Overridepublic Shape createShape() {return new Circle();}
}// 三角形工厂
public class TriangleFactory extends ShapeFactory {@Overridepublic Shape createShape() {return new Triangle();}
}// 测试类
public class TestMethodFactory {public static void main(String[] args) {ShapeFactory circleFactory = new CircleFactory();Shape circle = circleFactory.createShape();circle.draw(); // 绘制圆形ShapeFactory triangleFactory = new TriangleFactory();Shape triangle = triangleFactory.createShape();triangle.draw(); // 绘制三角形}
}
4. 运行结果
当我们运行 TestMethodFactory 类时,会得到如下输出:
画了一个圆
画了一个三角形
5. 分析
ShapeFactory类作为抽象工厂类,声明了createShape()方法,具体的工厂类CircleFactory和TriangleFactory实现了这个方法,分别返回了不同的图形对象。TestMethodFactory类作为客户端,使用了不同的工厂来创建不同的图形对象,而无需关注图形的具体创建过程。
6. 总结
通过本次练习,我们深入了解了工厂方法模式的应用。工厂方法模式通过将对象创建逻辑交给子类来实现,使得代码更加解耦,易于扩展。如果以后需要增加新的图形类型,只需添加新的工厂类和对应的图形类,而不需要修改客户端代码。这种设计模式符合 开闭原则,能够使代码在面对变化时更加灵活。
三、总结与反思
- 工厂方法模式帮助我们解决了创建对象的问题,将对象的创建交给工厂方法,避免了客户端直接依赖于具体的实现类。
- 它使得我们能够灵活地扩展系统功能,如需要增加新的图形类型,只需添加新的工厂类。
- 通过工厂方法模式,客户端无需知道具体的创建逻辑,只关心工厂返回的产品对象,从而简化了代码的使用和维护。
如果你对工厂方法模式有任何疑问或想法,欢迎在评论区留言交流!
希望这篇博客能帮助你更好地理解工厂方法模式。如果你有任何问题,或者想要更多的设计模式实例,请随时向我提问!
相关文章:
12 设计模式之工厂方法模式
一、什么是工厂方法模式? 1.定义 在软件开发中,设计模式 是解决常见软件设计问题的最佳实践。而 工厂方法模式(Factory Method Pattern) 作为创建型设计模式之一,常常被用来解决对象创建问题。它通过将对象的创建交给…...
spaCy 入门与实战:强大的自然语言处理库
spaCy 入门与实战:强大的自然语言处理库 spaCy 是一个现代化、工业级的自然语言处理(NLP)库,以高效、易用和功能丰富著称。它被广泛应用于文本处理、信息提取和机器学习任务中。本文将介绍 spaCy 的核心功能,并通过一…...
python包的管理和安装——笔记
1.列出包 pip list pip freeze 用这2个可以查看当前python 下所有的包和版本,还有下载地址 如果只是想导出当前的环境 可以用 2.安装pipreqs pip install pipreqs,pipreqs ./可以导出当前项目的包这个包 遇到编码报错 pipreqs ./ --encodingutf8 p…...
Vue前端页面内嵌套本项目iframe窗口的通信传输方式
一、目的 想要在iframe中使用本项目页面、并能够与其父页面组件实现实时通信。Vue前端页面内嵌套本项目iframe窗口的通信传输方式-星林社区 https://www.jl1mall.com/forum/PostDetail?postId20241202172800023969 二、iframe通信方式 1.接收消息 页面需要监听 message 事件…...
【WEB开发.js】addEventListener事件监听器的绑定和执行次数的问题(小心踩坑)
假设我们有一个按钮,用户点击该按钮后,会选择一个文件,且我们希望每次点击按钮时只触发一次文件处理。下面我会给你一个简单的例子,展示放在函数内部和放在函数外部的区别。 1. 将事件监听器放在函数内部(问题的根源&…...
用于LiDAR测量的1.58um单芯片MOPA(一)
--翻译自M. Faugeron、M. Krakowski1等人2014年的文章 1.简介 如今,人们对高功率半导体器件的兴趣日益浓厚,这些器件主要用于遥测、激光雷达系统或自由空间通信等应用。与固态激光器相比,半导体器件更紧凑且功耗更低,这在低功率供…...
【GPT】代谢概念解读
以下是对代谢中分解代谢和合成代谢两个概念的深入解读,用简单易懂的方式展开说明: 1. 分解代谢(Catabolism) 什么是分解代谢? 分解代谢是身体把大分子“拆开”的过程。就像把一个三明治分解成面包片、肉片和菜叶&#…...
Devops-git篇-01-git环境配置
环境配置 设置用户签名 配置用户名: git config --global user.name 你的用户名 配置邮箱: git config --global user.email 注册的邮箱 配置好之后,可以用git config --global --list命令查看配置是否OK $ git config --global --list u…...
STM32 HAL库开发学习1.STM32CubeMX 新建工程
STM32 HAL库开发学习1.STM32CubeMX 新建工程 一、 STM32 CubeMX 下载二、CubeMX 功能介绍1. 固件包路径设置2. 新建工程 三、创建项目实例1. 新建项目2. GPIO 管脚设置3. GPIO 窗口配置4. 调试设置5. 时钟配置6. 项目管理(1)项目信息(2&#…...
JS学习(2)(浏览器执行JS过程、JS的ECMAScript、DOM、BOM)
目录 一、浏览器如何执行JS? (1)浏览器主要的组成部分。 1、渲染引擎。 2、JS引擎。 (2)演示。 二、JS的组成。 (1)JS主要由三部分组成。 1、JS基础。 2、JS-API。 (2)EC…...
如何解决服务器扫描出的ASP木马问题
随着互联网的发展,网站安全问题日益凸显。其中,ASP(Active Server Pages)木马因其隐蔽性和危害性成为攻击者常用的手段之一。本文将详细介绍如何检测和清除服务器上的ASP木马,以保障网站的安全。 1. ASP木马概述 ASP…...
SpringBoot 架构助力夕阳红公寓管理系统可持续发展战略
摘 要 如今社会上各行各业,都在用属于自己专用的软件来进行工作,互联网发展到这个时候,人们已经发现离不开了互联网。互联网的发展,离不开一些新的技术,而新技术的产生往往是为了解决现有问题而产生的。针对于夕阳红公…...
TCP、HTTP、RPC
一、TCP (Transmission Control Protocol) 定义 TCP(传输控制协议)是一种面向连接、可靠传输的传输层协议,用于在计算机网络中提供端到端的数据通信服务。它是互联网协议套件的一部分,与IP(互联网协议)一…...
《C++ 中 RNN 及其变体梯度问题的深度剖析与解决之道》
在当今人工智能蓬勃发展的浪潮中,递归神经网络(RNN)及其变体长短期记忆网络(LSTM)和门控循环单元(GRU)在处理序列数据方面展现出了强大的潜力。然而,当我们在 C中着手实现这些网络时…...
TypeScript 在 React 中的应用
文章目录 前言一、为什么要在 React 中使用 TypeScript?二、如何在React中使用 TypeScript三、高级类型结语 前言 随着前端开发的复杂度不断提升,开发者对于代码质量、可维护性和开发效率的要求也日益增高。TypeScript 作为一种为 JavaScript 添加静态类…...
黑马2024AI+JavaWeb开发入门Day07-部门管理-日志技术飞书作业
视频地址:哔哩哔哩 讲义作业飞书地址:day07作业 完成新增班级和查询班级的接口开发 1、ClazzController.java package org.example.controller;import lombok.extern.slf4j.Slf4j; import org.example.pojo.Clazz; import org.example.service.Clazz…...
UIlicious - 自动化端到端测试
在现代软件开发中,测试自动化已然成为产品交付质量的基石。而端到端测试(E2E),作为验证整个应用流畅运行的关键,常常是测试工作中最具挑战性的一环。这时,一款简单高效的自动化测试工具——UIlicious&#…...
JMeter中获取随机数、唯一ID、时间日期(包括当前日期增减)截取指定位数的字符等
在JMeter中,您可以使用内置的函数和一些额外的插件来获取随机数、唯一ID、时间日期以及截取指定位数的字符。以下是一些常用的方法: 获取随机数: 使用__Random函数,您可以在指定的最小值和最大值之间生成一个随机数。例如…...
构建自己的docker的ftp镜像
aarch64系统可运行的docker镜像 构建自己的vsftpd镜像,我是在windows系统下的docker desktop中构建运行于aarch64 GNU/Linux系统的ftp镜像。 系统环境: Welcome to Debian GNU/Linux with Linux x.x.x dockerfile FROM ubuntu:latestUSER rootRUN ap…...
人机交互革命,为智能座舱市场激战注入一针「催化剂」
从AIGC到AGI赋能,智能座舱人机交互体验迎来新范式。 不断训练、迭代的大模型,为智能座舱带来了更全面的感知能力、更准确的认知理解,以及更丰富的交互模态,显著提升了其智能化水平。 “AI大模型的快速应用与迭代,推动…...
PingFangSC字体全面应用指南:从价值解析到性能优化的实践方案
PingFangSC字体全面应用指南:从价值解析到性能优化的实践方案 【免费下载链接】PingFangSC PingFangSC字体包文件、苹果平方字体文件,包含ttf和woff2格式 项目地址: https://gitcode.com/gh_mirrors/pi/PingFangSC 价值定位:为什么Pin…...
2.2.2.3 Spark实战:词频统计
本次实战涵盖了Spark词频统计(WordCount)的两种主流实现方式。首先,利用Scala在spark-shell中完成从读取文件、flatMap分词、map映射到reduceByKey聚合的完整流程,并实现结果的降序排序。其次,针对Spark 3.3.2版本的需…...
Qt5.14.2与VS2019整合开发避坑指南(从安装到第一个GUI项目)
Qt5.14.2与VS2019整合开发避坑指南(从安装到第一个GUI项目) 在Windows平台进行Qt开发时,Visual Studio作为强大的IDE环境,与Qt框架的结合能够显著提升开发效率。本文将深入剖析Qt5.14.2与VS2019整合过程中的关键环节,从…...
translategemma-4b-it优化升级:Ollama部署后提升翻译质量的4个技巧
translategemma-4b-it优化升级:Ollama部署后提升翻译质量的4个技巧 你已经成功用Ollama部署了translategemma-4b-it,看着它把图片里的英文变成中文,是不是觉得挺神奇的?但用了几次后,你可能会发现一些问题:…...
Phi-4-mini-reasoning 128K上下文应用创新:法律条文交叉引用推理案例
Phi-4-mini-reasoning 128K上下文应用创新:法律条文交叉引用推理案例 1. 模型简介与核心能力 Phi-4-mini-reasoning 是一个轻量级开源模型,专注于高质量推理任务。作为Phi-4模型家族成员,它通过合成数据训练和微调,特别擅长处理…...
一开口就聊到客户心坎里的沟通话术
先把人聊顺,事自然就顺了一位资深顾问,老客户复购和转介绍特别多。她的秘诀很简单:先聊人,再聊事。有次对接一位态度疏离的客户,她没直接问方案,而是看到客户朋友圈刚出去玩,便说:“…...
如何高效突破内容付费墙:Bypass Paywalls Clean浏览器扩展深度技术解析
如何高效突破内容付费墙:Bypass Paywalls Clean浏览器扩展深度技术解析 【免费下载链接】bypass-paywalls-chrome-clean 项目地址: https://gitcode.com/GitHub_Trending/by/bypass-paywalls-chrome-clean 在数字内容访问受限的时代,Bypass Payw…...
保姆级教程:用yangipcclient RN SDK 8.0快速给你的App加上实时对讲功能
保姆级实战:React Native应用集成实时对讲功能的完整指南 想象一下,你正在开发一款智能家居控制应用,用户反馈最强烈的需求是能够直接与家中的设备进行语音对讲。或者你负责的教育类App,小组讨论时缺少高效的实时语音沟通工具。传…...
YOLO12模型与GitHub Actions结合:自动化测试与部署流水线
YOLO12模型与GitHub Actions结合:自动化测试与部署流水线 1. 引言 在目标检测项目的开发过程中,我们经常面临这样的挑战:每次修改代码后都需要手动运行测试、构建镜像、部署模型,这个过程既耗时又容易出错。特别是对于YOLO12这样…...
iOSDeviceSupport:解决设备调试兼容性问题的高效管理工具
iOSDeviceSupport:解决设备调试兼容性问题的高效管理工具 【免费下载链接】iOSDeviceSupport All versions of iOS Device Support 项目地址: https://gitcode.com/gh_mirrors/ios/iOSDeviceSupport 问题场景:当新系统遇见旧Xcode "连接失败…...
