工厂方法模式
在开发组件的时候比如button、text等,需要对这些组件做比较多的初始化工作,比如初始化长度等。传统的开发方案如下:

图 传统开发方案UML
上面的方案组件创建及组件的其他业务操作耦合在一起,违背了单一职责原则;在客户端Client需要知道具体的组件类名,才能创建对应的组件。
1 工厂方法模式概述
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级。

图 工厂方法模式UML
Product: 抽象产品类,是工厂模式所创建对象的超类型,也是产品对象的公共父类。
ConcreteProduct: 具体的产品类,由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
Factory: 抽象工厂类,声名了创建产品的方法,是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
ConcreteFactory: 具体的工厂类,实现了抽象工厂类中定义的工厂方法,可有客户端调用,返回一个具体产品类的实例。
1.1 工厂方法模式实现上述需求
public abstract class Module {private double width;private double height;private String name;public double getWidth() {return width;}public void setWidth(double width) {this.width = width;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return name + "{" +"width=" + width +", height=" + height +'}';}
}public class ButtonModule extends Module{}public class TextModule extends Module{
}/*** 在开发组件的时候比如button、text等,需要对这些组件做比较多的初始化工作,比如初始化长度等。*/
public interface Factory {Module create();}public class ButtonFactory implements Factory{@Overridepublic Module create() {ButtonModule module = new ButtonModule();module.setHeight(100.0);module.setName("button");// 其他初始化工作return module;}
}public class TextFactory implements Factory{@Overridepublic Module create() {TextModule textModule = new TextModule();textModule.setName("text");textModule.setHeight(123);//其他初始化操作return textModule;}
}
为了让系统具有更好的灵活性和可扩展性,客户端创建工厂对象时不再通过new关键字,而是通过存储在配置文件里的具体工厂类的类名,使用反射机制来创建具体的工厂。优化如下:
<?xml version="1.0" encoding="UTF-8"?>
<config><className>com.huangmingfu.factory_method.ButtonFactory</className>
</config>public class FactoryMethodXmlUtil {public static Object getBean() {try {DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();DocumentBuilder documentBuilder = dFactory.newDocumentBuilder();Document document = documentBuilder.parse(FactoryMethodXmlUtil.class.getClassLoader().getResourceAsStream("factory_method/concrete-factory.xml"));NodeList nodeList = document.getElementsByTagName("className");Node node = nodeList.item(0).getFirstChild();String className = node.getNodeValue();Class<?> aClass = Class.forName(className);return aClass.newInstance();} catch (Exception e) {e.printStackTrace();return null;}}}public class Client {public static void main(String[] args) {Factory factory;factory = (Factory) FactoryMethodXmlUtil.getBean();assert factory != null;System.out.println(factory.getClass());Module module = factory.create();System.out.println(module);}}
2 优缺点
2.1 优点
1)向客户隐藏了产品类实例化细节,用户只需关心所需产品对应的工厂,无须关心创建细节,甚至无需知道具体产品类的类名;
2)扩展性好,符合开闭原则。
2.2 缺点
1)添加新的产品时,需要编写新的具体产品类及对应的具体工厂类,使得系统中类的个数成对增加,增加了系统复杂度及开销。
3 适用场景
- 客户不知道所需要的对象的类,只知道所对应的工厂。
- 对象创建时,需初始化操作多。
相关文章:
工厂方法模式
在开发组件的时候比如button、text等,需要对这些组件做比较多的初始化工作,比如初始化长度等。传统的开发方案如下: 图 传统开发方案UML 上面的方案组件创建及组件的其他业务操作耦合在一起,违背了单一职责原则;在客户…...
(CentOS 7)nvidia-smi:Failed to initialize NVML: Driver/library version mismatch
[CentOS 7]nvidia-smi:Failed to initialize NVML: Driver/library version mismatch 问题源头: nvidia-smi \text{nvidia-smi} nvidia-smi报错问题 CUDA \text{CUDA} CUDA安装时的问题 这里仅描述自身发现的一种情况,希望对大家有所帮助。 问题源头&…...
呼吸灯——FPGA
文章目录 前言一、呼吸灯是什么?1、介绍2、占空比调节示意图 二、系统设计1、系统框图2、RTL视图 三、源码四、效果五、总结六、参考资料 前言 环境: 1、Quartus18.0 2、vscode 3、板子型号:EP4CE6F17C8 要求: 将四个LED灯实现循环…...
群辉用户接入vocechat的方法(附开通GPT机器人)
群辉安装聊天服务器-加入chatgpt vocechat项目简单的使用介绍集成群辉帐号系统登陆vocechat 第二章接入chatgpt这是一个机器人的演示 这是个处于发展中的不错的项目吧,才感觉到好神奇。有意思。 vocechat项目简单的使用介绍 昨天的找群辉文章的时候看到了vocechat&…...
flutter js交互传参
加载网页的webView WebView(initialUrl:http://test/h5atui//#/mobileMaps?lng${CommonConfig.lng}&lat${CommonConfig.lat},javascriptMode: JavascriptMode.unrestricted,onWebViewCreated: (controller) {_webViewController controller;},onProgress: (process){set…...
重磅IntelliJ IDEA 2023.2 新版本即将发布,拥抱 AI
IntelliJ IDEA 近期连续发布多个EAP版本,官方在对用户体验不断优化的同时,也新增了一些不错的功能,尤其是人工智能助手补充,AI Assistant,相信在后续IDEA使用中,会对开发者工作效率带来不错的提升。 以下是…...
JavaWeb_SpringCloud微服务_Day1-eureka, ribbon, nacos
JavaWeb_SpringCloud微服务_Day1-eureka, ribbon, nacos 认识微服务微服务技术对比 分布式服务架构案例远程调用 eureka注册中心原理搭建EurekaServer服务注册服务发现 Ribbon负载均衡修改负载均衡饥饿加载 nacos注册中心快速入门eureka和nacos对比 来源 认识微服务 微服务技术…...
数据科学领域常用python库
pandas Pandas 的名称源自 “ panel data ”,这是一个计量经济学术语,用于表示多维结构化数据集和 “ Python 数据分析”。众所周知,清理和转换数据在数据分析中非常重要,Pandas 提供了丰富的数据结构和功能,使数据处…...
【Android关键字】startActivityForResult/onActivityResult/setResult方法的使用
最近在写一个安卓程序,在程序里需要用到startActivityForResult这个Intent操作关键字,与该关键字有关的还有onActivityResult和setResult。这里对其用法进行一个总结。 三者在API中的形式 //startActivityForResult与startActivity类似,只不…...
PyTorch深度学习实战(5)——计算机视觉
PyTorch深度学习实战(5)——计算机视觉 0. 前言1. 图像表示2. 将图像转换为结构化数组2.1 灰度图像表示2.2 彩色图像表示 3 利用神经网络进行图像分析的优势小结系列链接 0. 前言 计算机视觉是指通过计算机系统对图像和视频进行处理和分析,利…...
遥感目标检测(1)--R3Det
目录 一、概述 二、三个挑战 三、网络架构编辑 1、旋转RetinaNet 2、精细化旋转RetinaNet 3、与RoIAlign(感兴趣区域插值)进行比较 4、消融实验与对比实验 一、概述 R3Det论文中提到一个端到端的精细化的单级旋转检测器,通过从粗到细…...
使用 vue3-tel-input电话组件时,为什么通过v-model绑定的默认值无效而 通过:value绑定有效?
问题: 使用第三方 vue3-tel-input电话组件时,通过v-model绑定具有初始值的电话变量,但input框内显示的初始值为空? 排查过程: 将 v-model绑定改为 :value绑定后,电话变量初始值竟然能够显示在vue3-tel-inp…...
【运维工程师学习二】OS系统管理
【运维工程师学习二】OS系统管理 1、操作系统管理2、进程管理3、进程的启动4、进程信息的查看4.1、STAT 进程的状态:进程状态使用字符表示的(STAT的状态码),其状态码对应的含义:4.2、ps命令常用用法(方便查看系统进程&…...
【前端技巧】CSS常用知识碎片(九)
CSS常用知识碎片(九) mask-image属性 带有半透明的PNG图像的遮罩效果 .mask-image {mask: no-repeat center / contain;mask-image: url(bird.png); }SVG图形遮罩效果 .mask-image {mask-image: url("data:image/svgxml,%3Csvg viewBox0 0 3232…...
SQL 上升的温度
197 上升的温度 SQL架构 表: Weather ---------------------- | Column Name | Type | ---------------------- | id | int | | recordDate | date | | temperature | int | ---------------------- id 是这个表的主键 该表包含特定日期的温度信息 编写一个 SQL …...
Matlab实现最优化(附上多个完整仿真源码)
最优化是一种寻找最优解的数学方法,它在各个领域都有广泛的应用。在Matlab中,有多种工具箱和函数库可以用来实现最优化,下面我们来介绍一下如何用Matlab实现最优化。 1. 定义目标函数 在开始最优化之前,需要定义一个目标函数。目…...
es下载历史的tar文件
第一步进入官网找到历史版本 第二步复制历史版本名称组合成下面的链接 直接get访问下载。如下链接所示只需要修改7.3.0这个版本号 https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.3.0-linux-x86_64.tar.gz...
顺畅下载chatglm2-6b的模型文件
不管是从huggingface下,git下,wget下,都可能卡。 用推荐的清华源的url下,也卡,但url转换之后的,在windows下不了。 但是在linux上就几十兆每秒 wget https://cloud.tsinghua.edu.cn/seafhttp/files/0d8b273…...
go语言 socket: too many open files 错误分析
问题背景: 近期针对老的PHP接口做了迁移重构,用golang重新实现,在上线之前,测试进行了压测,压测的量级为:200请求/s, 连续请求10s,发现接口出现大量超时错误,查看日志发现错误信息为…...
分布式搜索--elasticsearch
一、初识 elasticsearch 1. 了解 ES ① elasticsearch 是一款非常强大的开源 搜索引擎,可以帮助我们从海量数据中 快速找到需要的内容 ② elasticsearch 结合 kibana、Logstash、 Beats,也就是 elastic stack (ELK),被 广泛应用在日志数据分…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
Webpack性能优化:构建速度与体积优化策略
一、构建速度优化 1、升级Webpack和Node.js 优化效果:Webpack 4比Webpack 3构建时间降低60%-98%。原因: V8引擎优化(for of替代forEach、Map/Set替代Object)。默认使用更快的md4哈希算法。AST直接从Loa…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文通过代码驱动的方式,系统讲解PyTorch核心概念和实战技巧,涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
