工厂方法模式深度解析:从原理到应用实战
作者简介
我是摘星,一名全栈开发者,专注 Java后端开发、AI工程化 与 云计算架构 领域,擅长Python技术栈。热衷于探索前沿技术,包括大模型应用、云原生解决方案及自动化工具开发。日常深耕技术实践,乐于分享实战经验与学习心得,希望用通俗易懂的方式帮助开发者快速掌握核心技术。持续输出AI、云计算及开源技术相关内容,欢迎关注交流!
目录
作者简介
1. 技术背景
2. 概念定义
2.1 工厂方法模式的定义
2.2 模式结构
3. 原理剖析
3.1 工厂方法模式的实现原理
3.2 创建过程分析
4. 技术实现
4.1 基础实现
4.2 参数化工厂方法
4.3 使用反射的通用工厂
5. 应用场景分布
5.1 详细应用场景分析
5.2 应用场景分布占比
5.3 使用频率占比
5.4 应用特征雷达
5.4 发展趋势
6. 实际案例
6.1 Java集合框架中的工厂方法
6.2 Spring框架中的BeanFactory
6.3 JDBC中的DriverManager
6.4 日志框架中的LoggerFactory
7. 优缺点分析
7.1 优点
7.2 缺点
8. 纵横对比
8.1 工厂方法模式 vs 简单工厂模式
8.2 工厂方法模式 vs 抽象工厂模式
9. 实战思考
9.1 何时使用工厂方法模式?
9.2 何时避免使用工厂方法模式?
9.3 设计建议
9.4 性能优化方向
10. 总结
1. 技术背景
在软件开发中,对象的创建是一个常见但复杂的问题。当系统需要根据不同的条件创建不同类型的对象时,直接使用new
操作符会导致代码高度耦合,难以维护和扩展。工厂方法模式(Factory Method Pattern)正是为解决这类对象创建问题而生的设计模式。
根据《设计模式:可复用面向对象软件的基础》(GoF)统计,工厂方法模式在框架设计中的使用率高达45%,是最常用的创建型模式之一。在Spring、Hibernate等主流框架中,工厂方法模式被广泛应用来实现灵活的组件创建机制。
2. 概念定义
2.1 工厂方法模式的定义
工厂方法模式定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。其核心特点包括:
- 抽象工厂接口:声明工厂方法
- 具体工厂类:实现工厂方法,创建具体产品
- 产品接口:定义产品的公共接口
- 具体产品类:实现产品接口
2.2 模式结构
图1:工厂方法模式类图
3. 原理剖析
3.1 工厂方法模式的实现原理
工厂方法模式通过将对象的创建过程抽象化,实现了:
- 解耦:将对象的创建与使用分离
- 扩展性:新增产品类型只需添加新的工厂类
- 多态性:通过接口或抽象类定义产品,支持多态
- 单一职责:每个工厂只负责创建一种产品
3.2 创建过程分析
图2:工厂方法模式时序图
4. 技术实现
4.1 基础实现
// 产品接口
public interface Product {void operation();
}// 具体产品A
public class ConcreteProductA implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductA operation");}
}// 具体产品B
public class ConcreteProductB implements Product {@Overridepublic void operation() {System.out.println("ConcreteProductB operation");}
}// 抽象工厂
public abstract class Creator {public abstract Product factoryMethod();public void someOperation() {Product product = factoryMethod();product.operation();}
}// 具体工厂A
public class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductA();}
}// 具体工厂B
public class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductB();}
}// 客户端代码
public class Client {public static void main(String[] args) {Creator creator = new ConcreteCreatorA();creator.someOperation();creator = new ConcreteCreatorB();creator.someOperation();}
}
4.2 参数化工厂方法
public abstract class Creator {public abstract Product factoryMethod(String type);
}public class ConcreteCreator extends Creator {@Overridepublic Product factoryMethod(String type) {switch (type) {case "A":return new ConcreteProductA();case "B":return new ConcreteProductB();default:throw new IllegalArgumentException("Unknown product type");}}
}
4.3 使用反射的通用工厂
public class GenericCreator {public static <T extends Product> T createProduct(Class<T> clazz) {try {return clazz.getDeclaredConstructor().newInstance();} catch (Exception e) {throw new RuntimeException("Failed to create product", e);}}
}// 使用方式
Product product = GenericCreator.createProduct(ConcreteProductA.class);
5. 应用场景分布
5.1 详细应用场景分析
工厂方法模式适用于以下场景:
- 框架设计:当框架需要为标准接口提供多种实现时
- 插件系统:当系统需要支持动态添加新组件时
- 跨平台应用:当需要为不同平台创建相应的UI组件时
- 测试驱动开发:当需要为测试提供模拟对象时
- 对象池管理:当需要控制对象创建过程以优化资源使用时
5.2 应用场景分布占比
图3:应用场景分布占比图
5.3 使用频率占比
图4:使用频率占比图
5.4 应用特征雷达
图5:应用特征雷达图
5.4 发展趋势
图6:发展趋势图
6. 实际案例
6.1 Java集合框架中的工厂方法
List<String> list = List.of("a", "b", "c"); // Java 9+ 工厂方法
Set<Integer> set = Set.of(1, 2, 3);
Map<String, Integer> map = Map.of("a", 1, "b", 2);
6.2 Spring框架中的BeanFactory
public interface BeanFactory {Object getBean(String name) throws BeansException;<T> T getBean(String name, Class<T> requiredType) throws BeansException;// 其他工厂方法...
}// 具体实现类
public class DefaultListableBeanFactory implements BeanFactory {// 实现工厂方法
}
6.3 JDBC中的DriverManager
Connection conn = DriverManager.getConnection(url, user, password);
6.4 日志框架中的LoggerFactory
// SLF4J示例
Logger logger = LoggerFactory.getLogger(MyClass.class);
7. 优缺点分析
7.1 优点
- 解耦:将对象的创建与使用分离
- 扩展性:添加新产品只需添加新的工厂类
- 可维护性:集中管理对象的创建逻辑
- 多态性:支持面向接口编程
- 单一职责:每个工厂类只负责创建一种产品
7.2 缺点
- 类数量增加:每个产品都需要对应的工厂类
- 抽象性增加:增加了系统的理解和设计难度
- 性能开销:相比直接实例化有额外的方法调用开销
- 不适用于简单对象:对于简单对象的创建可能过度设计
图4:工厂方法模式优缺点分析图
8. 纵横对比
8.1 工厂方法模式 vs 简单工厂模式
对比项 | 工厂方法模式 | 简单工厂模式 |
结构复杂度 | 较高 | 较低 |
扩展性 | 好(OCP原则) | 差(需修改工厂类) |
灵活性 | 高 | 低 |
适用场景 | 复杂对象创建 | 简单对象创建 |
类数量 | 较多 | 较少 |
8.2 工厂方法模式 vs 抽象工厂模式
对比项 | 工厂方法模式 | 抽象工厂模式 |
创建对象 | 单一产品 | 产品族 |
方法数量 | 一个工厂方法 | 多个工厂方法 |
层次结构 | 单层抽象 | 双层抽象 |
扩展方向 | 垂直扩展(新产品) | 水平扩展(新产品族) |
复杂度 | 较低 | 较高 |
9. 实战思考
9.1 何时使用工厂方法模式?
- 当系统需要独立于其产品的创建、组合和表示时
- 当系统需要配置多个产品系列中的一个时
- 当需要强调设计可扩展性时
- 当需要隐藏具体产品类的实现时
9.2 何时避免使用工厂方法模式?
- 当对象的创建逻辑简单且不会变化时
- 当性能要求极高,不能接受额外方法调用开销时
- 当系统不需要多态性和扩展性时
- 当产品种类极少且不会增加时
9.3 设计建议
- 考虑使用模板方法:将工厂方法与模板方法结合
- 参数化工厂方法:通过参数决定创建哪种产品
- 使用依赖注入:结合IoC容器管理工厂
- 保护性设计:为工厂方法添加适当的访问控制
9.4 性能优化方向
- 对象池技术:重用已创建的对象
- 缓存机制:缓存常用产品实例
- 延迟初始化:仅在需要时创建对象
- 原型模式:通过克隆避免重复创建
10. 总结
工厂方法模式是一种强大而灵活的设计模式,它通过将对象的创建过程抽象化,实现了:
- 创建逻辑与使用逻辑的解耦
- 系统扩展性的显著提升
- 面向接口编程的良好实践
- 框架设计的核心模式之一
在实际开发中,我们应该根据具体场景选择合适的工厂实现方式。对于简单场景,可以考虑简单工厂;对于复杂场景,工厂方法模式或抽象工厂模式可能更合适。随着现代框架的发展,工厂方法模式常与依赖注入、IoC容器等技术结合使用,发挥更大的威力。
权威参考:
- Design Patterns: Elements of Reusable Object-Oriented Software (GoF经典著作)
- Refactoring Guru - Factory Method (模式详解)
- Spring Framework Documentation - The IoC Container (工厂模式在Spring中的应用)
- Effective Java 3rd Edition - Item 1: Consider static factory methods instead of constructors (Joshua Bloch)
相关文章:

工厂方法模式深度解析:从原理到应用实战
作者简介 我是摘星,一名全栈开发者,专注 Java后端开发、AI工程化 与 云计算架构 领域,擅长Python技术栈。热衷于探索前沿技术,包括大模型应用、云原生解决方案及自动化工具开发。日常深耕技术实践,乐于分享实战经验与…...
TS 星际通信指南:从 TCP 到 UDP 的宇宙漫游
文章目录 一、计算机网络通信1、基本概念2、核心要素(一)终端设备(二)通信介质(三)网络协议 3、常用通信模型(一)OSI 七层模型(理论框架)(二&…...

python可视化:端午假期旅游火爆原因分析
python可视化:端午假期旅游火爆原因分析 2025年的旅游市场表现强劲: 2025年端午假期全社会跨区域人员流动量累计6.57亿人次,日均2.19亿人次,同比增长3.0%。入境游订单同比大涨近90%,门票交易额(GMV&#…...
Missashe考研日记—Day51-Day57
Missashe考研日记—Day51-Day57 写在面前 本系列博客用于记录博主一周的学习进度。线代题型总结 专业课408 这周简直是拼命学计网,花了两三天速通传输层和应用层内容,又臭又长的网课听不下去一点了,赶紧结束准备开二轮进行复习和刷题了。…...
electron-vite_18桌面共享
electron默认不支持桌面共享,需要添加desktopCapturer配置,这样在使用navigator.mediaDevices.getUserMedia API访问可用于从桌面捕获音频和视频的媒体源的信息。 electron版本 "electron": "^31.0.2",在main.js中添加desktopCaptu…...

SOC-ESP32S3部分:28-BLE低功耗蓝牙
飞书文档https://x509p6c8to.feishu.cn/wiki/CHcowZMLtiinuBkRhExcZN7Ynmc 蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换,下图是一个蓝牙应用的分层架构,Application部分则是我们需要实现的内容,Protoc…...

Git-flow流
Git git是版本控制软件,一般用来做代码版本控制 github是一个免费版本控制仓库是国内外很多开源项目的集中地,其本体是一个git服务器 Git初始化操作 git init 初始化仓库 git status 查看当前仓库的状态 git add . 将改动的文件加到暂存区 gi…...

VirtualBox给Rock Linux9.x配置网络
写这篇文章之前,先说明一下,我参考的是我之前写的《VirtualBox Linux网络配置》 我从CentOS7转到了Rock9,和配置Centos7一样,主流程没有变化,变化的是Rock9.x中的配置文件和使用的命令。 我再说一次,因为主…...

知识图谱增强的大型语言模型编辑
https://arxiv.org/pdf/2402.13593 摘要 大型语言模型(LLM)是推进自然语言处理(NLP)任务的关键,但其效率受到不准确和过时知识的阻碍。模型编辑是解决这些挑战的一个有前途的解决方案。然而,现有的编辑方法…...

.NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
在当今数据驱动的时代,向量数据库(Vector Database)作为一种新兴的数据库技术,正逐渐成为软件开发领域的重要组成部分。特别是在 .NET 生态系统中,向量数据库的应用为开发者提供了构建智能、高效应用程序的新途径。 一…...

【claude+deepseek+gemini】基于李群李代数和螺旋理论工业机器人控制系统软件UI设计
claude的首次设计html是最佳的。之后让deepseek和gemini根据claude的UI设计进行改进设计。。。当然可以尝试很多次,也可以让他们之间来回不断改进…… claude deepseek-r1 0528 上图为deepseek首次设计,下面为改进设计 …… Gemini 2.5 Pro 0506 &#x…...

阿里云国际站,如何通过代理商邀请的链接注册账号
阿里云国际站:如何通过代理商邀请链接注册,解锁“云端超能力”与专属福利? 渴望在全球化浪潮中抢占先机?想获得阿里云国际站的海量云资源、遍布全球的加速节点与前沿AI服务,同时又能享受专属折扣、VIP级增值服务支持或…...

乾坤qiankun的使用
vue2 为主应用 react 为子应用 在项目中安装乾坤 yarn add qiankun # 或者 npm i qiankun -Svue主应用 在main.js中新增 (需要注意的是路由模型为history模式) registerMicroApps([{name: reactApp,entry: //localhost:3011,container: #container,/…...
从仿射矩阵得到旋转量平移量缩放量
仿射变换原理 仿射变换是一种线性变换,可以包括平移、旋转、缩放和剪切等操作。其一般公式可以表示为: $$\mathbf{x’} A \mathbf{x} \mathbf{b} ] 其中: (\mathbf{x}) 是输入向量,通常表示一个点在二维或三维空间中的坐标。(…...
Dockerfile 使用多阶段构建(build 阶段 → release 阶段)后端配置
错误Dockerfile配置示例: FROM python:3.11 as buildENV http_proxyhttp://172.17.0.1:7890 ENV https_proxyhttp://172.17.0.1:7890WORKDIR /appENV PYTHONPATH/app# Install Poetry # RUN curl -sSL https://install.python-poetry.org | POETRY_HOME/opt/poetry…...
Docker 镜像深度剖析:构建、管理与优化
一、前言 在容器化浪潮中,Docker镜像已成为构建可移植、标准化部署服务的基石。优质的镜像不仅能提升构建效率,更显著影响运行时性能和资源利用率。 本文将深入剖析Docker镜像的底层架构与工作原理,并通过实战案例详细演示镜像构建与优化技巧…...
使用 Flutter 开发 App 时,想要根据 Figma 设计稿开发出响应式 UI 界面
在使用 Flutter 开发 App 时,想要根据 Figma 设计稿开发出响应式 UI 界面(Responsive UI),以适配不同尺寸和分辨率的手机设备,需要从 设计阶段 和 编码实现阶段 双向配合。以下是详细的实现思路与方法: &am…...
Flink2.0及Flink-operater在K8S上部署
1.查找镜像 dockerhub访问不了的可以访问这个查找镜像 https://docker.aityp.com/ 在docker服务器上拉取flink镜像到本地 拉取镜像到你的docker服务器本地 docker pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/apache/flink:2.0.0-scala_2.12-java17 将docker服…...

PH热榜 | 2025-06-03
1. Knowledge 标语:像认识朋友一样去销售给潜在客户,因为你其实了解他们! 介绍:Knowledge 是一个针对个人的销售智能平台,它利用行为数据和心理测评来识别市场上的潜在买家,并指导销售团队以最真实、最有…...

论文略读: STREAMLINING REDUNDANT LAYERS TO COMPRESS LARGE LANGUAGE MODELS
2025 ICLR 判断模型层的重要性->剪去不重要的层(用轻量网络代替) 这种方法只减少了层数量,所以可以用常用的方法加载模型 层剪枝阶段 通过输入与输出的余弦相似度来判断各个层的重要性 具有高余弦相似度的层倾向于聚集在一起,…...

mapbox高阶,生成并加载等时图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.2 ☘️mapboxgl.Map style属性1.3 ☘️Fill面图层样式1.4 ☘️symbol符号图层…...
深入剖析物联网边缘计算技术:架构、应用与挑战
在物联网(IoT)蓬勃发展的当下,海量设备产生的数据如潮水般涌来,对数据处理和响应速度提出了前所未有的挑战。边缘计算技术应运而生,成为物联网领域的关键支撑技术之一。它就像在物联网网络的“边缘”部署了一个个智能小…...

DeepSeek眼中的文明印记:山海经
一、山海经到底是怎么回事? 《山海经》是中国古代一部极具神秘色彩的文化典籍,成书时间跨度较大(大致从战国至汉代),内容庞杂,涉及神话、地理、物产、巫术、医学、民俗等多个领域。关于它的性质࿰…...

在Mathematica中实现Newton-Raphson迭代
为了寻找方程 可以使用Newton-Raphson迭代方法: NRIter[func_, xzero_, n_ : 5] :Module[{pointlist {}, x, xold xzero, xnew, f, df, xl, xr, k},f[x_] func[x];df[x_] D[func[x], x];Do[(pointlist Join[pointlist, {{xold, 0}}, {{xold, f[xold]}}];xnew …...

【Ragflow】25.Ragflow-plus开发日志:excel文件解析新思路/公式解析适配
引言 RagflowPlus v0.3.0 版本中,增加了对excel文件的解析支持,但收到反馈,说效果并不佳。 以下测试文件内容来自群友反馈提供,数据已脱敏处理。 经系统解析后,分块效果如下: 可以看到,由于该…...

Python数据可视化科技图表绘制系列教程(一)
目录 创建多个坐标图形(坐标系) 图表的组成 创建图形与子图 创建子图1 创建子图2 创建子图3 创建子图4 创建子图5 添加图表元素 极坐标图1 极坐标图2 【声明】:未经版权人书面许可,任何单位或个人不得以任何形式复制、…...

移除3D对象的某些部分点云
1,目的 移除3D对象指定区域的点云。效果 2,原理。 通过投影剔除指定区域外的点云数据。 3,主要的算子。 3.1,gen_image_gray_ramp 是 Halcon 中用于生成线性灰度渐变图像的算子 功能概述 数学原理 生成的图像灰度值…...

阿里云为何,一个邮箱绑定了两个账号
阿里云“幽灵账号”之谜:同一个邮箱注销后仍有两个账号?深度揭秘成因与终极解决方案! 你是否曾在阿里云上使用同一个邮箱注册过多个账号,明明已经**“彻底”注销了其中一个**,却惊愕地发现系统里依然**“幽灵般”挂着…...

高效视频倍速播放插件推荐
软件介绍 本文介绍一款名为Global Speed的视频速度控制插件,该插件在插件市场评分极高,被公认为目前最好用的视频倍速插件之一。 插件安装与基本功能 安装Global Speed插件后,用户只需点击插件图标即可选择播放倍数,最高支持16…...

无他相机:专业摄影,触手可及
在数字摄影时代,手机摄影已成为许多人记录生活、表达创意的重要方式。无他相机正是这样一款专为摄影爱好者设计的相机应用程序,它不仅提供了专业级摄影设备的大部分功能,还通过简洁直观的操作界面,让每一位用户都能轻松上手&#…...