工厂方法模式的概述和使用
目录
- 一、工厂方法模式概述
- 1. 定义
- 2. 使用动机
- 二、工厂方法模式结构
- 1. 模式结构
- 2. 时序图
- 三、工厂方法模式的使用实例
- 四、工厂方法模式的优缺点
- 五、工厂方法模式在Java中应用
原文链接
一、工厂方法模式概述
1. 定义
工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。
在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
2. 使用动机
不再设计一个按钮工厂类来统一负责所有产品的创建,而是将具体按钮的创建过程交给专门的工厂子类去完成。
我们先定义一个抽象的按钮工厂类,再定义具体的工厂类来生成圆形按钮、矩形按钮、菱形按钮等,它们实现在抽象按钮工厂类中定义的方法。这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引进新的产品,如果出现新的按钮类型,只需要为这种新类型的按钮创建一个具体的工厂类就可以获得该新按钮的实例,这一特点无疑使得工厂方法模式具有超越简单工厂模式的优越性,更加符合“开闭原则”。
二、工厂方法模式结构
1. 模式结构
工厂方法模式包含如下角色:
●Product:抽象产品,工厂方法模式所创建的对象的超类,也就是所有产品类的共同父类或共同拥有的接口。在实际的系统中,这个角色也常常使用抽象类实现。
●ConcreteProduct:具体产品,这个角色实现了抽象产品(Product)所声明的接口,工厂方法模式所创建的每一个对象都是某个具体产品的实例。
●Factory:抽象工厂,担任这个角色的是工厂方法模式的核心,任何在模式中创建对象的工厂类必须实现这个接口。在实际的系统中,这个角色也常常使用抽象类实现。
●ConcreteFactory:具体工厂,担任这个角色的是实现了抽象工厂接口的具体Java类。具体工厂角色含有与业务密切相关的逻辑,并且受到使用者的调用以创建具体产品对象。
2. 时序图
-
先调用具体工厂对象中的方法createProduct()
-
根据传入产品类型参数(也可以无参),获得具体的产品对象
-
返回产品对象并使用
三、工厂方法模式的使用实例
上面的类图中,在动物这个类中,有猫和狗两种动物,并且都实现了动物吃东西的本领(方法)。在工厂类下,有各种管理具体动物的子工厂负责管理相应的两种动物。
抽象产品类:Animal
public abstract class Animal {public abstract void eat();
}
具体产品类:CatFactory
public class CatFactory implements Factory{@Overridepublic Animal creatAnimal() {return new Cat();}
}
具体产品类:DogFatory
public class DogFatory implements Factory{@Overridepublic Animal creatAnimal() {return new Dog();}
}
抽象工厂接口:Factory
public interface Factory {public abstract Animal creatAnimal();
}
具体工厂类:DogFatory
public class DogFatory implements Factory{@Overridepublic Animal creatAnimal() {return new Dog();}
}
具体工厂类:CatFactory
public class CatFactory implements Factory{@Overridepublic Animal creatAnimal() {return new Cat();}
}
测试类:
public class Test {public static void main(String[]args){
DogFatory dogFatory = new DogFatory();
Dog d = (Dog) dogFatory.creatAnimal();
d.eat();CatFactory catFactory = new CatFactory();
Cat c = (Cat) catFactory.creatAnimal();
c.eat();}
}
输出结果:
通过一个引用变量dogFatory / catFactory来创建产品对象,创建何种产品对象由指向的具体工厂类决定。通过工厂方法模式,将具体的应用逻辑和产品的创建分离开,促进松耦合。
四、工厂方法模式的优缺点
-
优点
-
在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
-
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
-
使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”,这点比简单工厂模式更优秀。
-
-
缺点
-
在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
-
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
-
-
适用场景
在以下情况下可以使用工厂方法模式:-
一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
-
一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
-
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
-
五、工厂方法模式在Java中应用
JDBC中的工厂方法:
Connection conn=DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=DB;user=sa;password=");
Statement statement=conn.createStatement();
ResultSet rs=statement.executeQuery("select * from UserInfo");
相关文章:

工厂方法模式的概述和使用
目录 一、工厂方法模式概述1. 定义2. 使用动机 二、工厂方法模式结构1. 模式结构2. 时序图 三、工厂方法模式的使用实例四、工厂方法模式的优缺点五、工厂方法模式在Java中应用 原文链接 一、工厂方法模式概述 1. 定义 工厂方法模式(Factory Method Pattern)又称为工厂模式&…...

HP惠普星15青春版/惠普小欧笔记本电脑15s-du1008tx原装出厂Win11系统
适用型号:15s-du1007tx、15s-du1008tx、15s-du1009tx、15s-du1010tx、15s-du1011tx、15s-du1012tx、15s-du1013tx 自带所有驱动、出厂主题壁纸LOGO、Office办公软件、惠普电脑管家等预装程序 所需要工具:32G或以上的U盘 文件格式:ISO 文件大…...

聊聊检索增强,LangChain一把梭能行吗?
背景 ChatGPT诞生之初,大家仿佛从中看到了未来:可以拿着大语言模型(LLM)这把锤子,锤遍业务上的钉子。其中最被看好的场景,莫过于搜索,不仅是微软、谷歌、百度这样的大公司将LLM用到自己的搜索业…...
【力扣】343. 整数拆分 <动态规划、数学>
【力扣】343. 整数拆分 给定一个正整数 n ,将其拆分为 k 个 正整数 的和( k > 2 ),并使这些整数的乘积最大化。返回可以获得的最大乘积 。 示例 1: 输入: n 2 输出: 1 解释: 2 1 1, 1 1 1。 示例 2: 输入: n 10 输出:…...
数据结构--5.1图的存储结构(十字链表、邻接多重表、边集数组)
目录 一、十字链表(Orthogonal List) 二、邻接多重表 三、边集数组 四、深度优先遍历 一、十字链表(Orthogonal List) 重新定义顶点表结点结构: datafirstInfirstOut 重新定义边表结构结点: tailV…...
mac上 Kratos 配置 protoc
前言 protoc 是 protobuf 文件(.proto)的编译器,可以借助这个工具把 .proto 文件转译成各种编程语言对应的源码,包含数据类型定义、调用接口等。 protoc 在设计上把 protobuf 和不同的语言解耦了,底层用 c 来实现 protobuf 结构的存储&#x…...

【c++5道练习题】①
目录 一、有限制的累加 二、计算日期到天数转换 三、仅仅反转字母 四、 字符串的第一个唯一字符 五、字符串最后一个单词的长度 一、有限制的累加 题述: 求123...n,要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句…...

最佳实践:TiDB 业务读变慢分析处理
作者:李文杰 网易游戏计费 TiDB 负责人 在使用或运维管理 TiDB 的过程中,大家几乎都遇到过 SQL 变慢的问题,尤其是查询相关的读变慢问题。读变慢的问题大部分情况下都遵循一定的规律,通过经验的积累可以快速的定位和优化ÿ…...

【ES6】Getter和Setter
JavaScript中的getter和setter方法可以用于访问和修改对象的属性。这些方法可以通过使用对象字面量或Object.defineProperty()方法来定义。 以下是使用getter和setter方法的示例: <!DOCTYPE html> <script>const cart {_wheels: 4,get wheels(){retu…...

3DS Max中绘制圆锥箭头
3DS Max中绘制圆锥箭头 绘制结果绘制过程步骤一:绘制立体圆锥方法1方法2 步骤二:圆锥体调参(模型尺寸设置)1圆锥体参数说明2圆锥体参数调整 步骤三:绘制圆柱体步骤四:圆柱体调参步骤五:圆锥与圆…...

虚拟机Ubuntu20.04 网络连接器图标开机不显示怎么办
执行以下指令: sudo service network-manager stop sudo rm /var/lib/NetworkManager/NetworkManager.state sudo service network-manager start...

你真的知道什么是USB Server吗?一分钟了解
很多公司都在用USB Server,效率大幅提高,但也还有不少人不知道USB Server到底是什么、干嘛用的。 USB Serve是帮助企业远程连接和集中管控USB设备的服务器 它的主要用途就是异地远程连接USB。 如,虚拟化环境的加密狗、前置机连接࿰…...

Node.js 中间件是怎样工作的?
express自带路由功能,可以侦听指定路径的请求,除此之外,express最大的优点就是【中间件】概念的灵活运用,使得各个模块得以解耦,像搭积木一样串起来就可以实现复杂的后端逻辑。除此之外,还可以利用别人写好…...

Spring MVC: 请求参数的获取
Spring MVC 前言通过 RequestParam 注解获取请求参数RequestParam用法 通过 ServletAPI 获取请求参数通过实体类对象获取请求参数附 前言 在 Spring MVC 介绍中,谈到前端控制器 DispatcherServlet 接收客户端请求,依据处理器映射 HandlerMapping 配置调…...
别再头疼反弹Shell失败了,这篇文章带你找到问题根源
别再头疼反弹Shell失败了,这篇文章带你找到问题根源 在渗透测试中,反弹shell失败的原因可以有多种。以下是一些常见的原因: **1.防火墙和网络过滤器:**目标系统可能配置了防火墙或网络过滤器,以限制对外部系统的连接…...

第五章 树与二叉树 四、线索树(手算与代码实现)
一、定义 1.线索树是一种二叉树,它在每个节点上增加了两个指针,分别指向其前驱和后继。 2.这些指针称为“线索”,因此线索树也叫做“线索化二叉树”。 3.在线索树中,所有的叶子节点都被线索化,使得遍历树的过程可以…...
服务器前后端学习理解
个人兴趣,突然想起来记录一下 1. 背景 想做一个最简单的网页,点击按钮后,访问服务器的redis数据库,读取一个为hello的值并显示 首先用js写了一个脚本,使用redis包,读取到了数据,并使用consol.l…...

python-数据分析-numpy、pandas、matplotlib的常用方法
一、numpy import numpy as np1.numpy 数组 和 list 的区别 输出方式不同 里面包含的元素类型 2.构造并访问二维数组 使用 索引/切片 访问ndarray元素 切片 左闭右开 np.array(list) 3.快捷构造高维数组 np.arange() np.random.randn() - - - 服从标准正态分布- - - …...

ChatGPT⼊门到精通(5):ChatGPT 和Claude区别
⼀、Claude介绍 Claude是Anthropic开发的⼀款⼈⼯智能助⼿。 官⽅⽹站: ⼆、Claude能做什么 它可以通过⾃然语⾔与您进⾏交互,理解您的问题并作出回复。Claude的主要功能包括: 1、问答功能 Claude可以解答⼴泛的常识问题与知识问题。⽆论是历史上的某个事件,理科…...

ChatGPT 总结数据分析的所有知识点
ChatGPT功能非常多,特别是对某个行业,某个方向,某个技术进行总结那是相当专业的。 如下图。 直接用一个指令便总结出来数据分析当中的所有知识点内容。 AIGC ChatGPT ,BI商业智能, 可视化Tableau, PowerBI, FineReport, 数据库Mysql Oracle, Office, Python ,ETL Ex…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...

Ubuntu Cursor升级成v1.0
0. 当前版本低 使用当前 Cursor v0.50时 GitHub Copilot Chat 打不开,快捷键也不好用,当看到 Cursor 升级后,还是蛮高兴的 1. 下载 Cursor 下载地址:https://www.cursor.com/cn/downloads 点击下载 Linux (x64) ,…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
Python爬虫实战:研究Restkit库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的有价值数据。如何高效地采集这些数据并将其应用于实际业务中,成为了许多企业和开发者关注的焦点。网络爬虫技术作为一种自动化的数据采集工具,可以帮助我们从网页中提取所需的信息。而 RESTful API …...