工厂方法模式
在开发组件的时候比如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),被 广泛应用在日志数据分…...
OpenClaw技能市场巡礼:ollama-QwQ-32B支持的10个高效自动化模块
OpenClaw技能市场巡礼:ollama-QwQ-32B支持的10个高效自动化模块 1. 为什么需要技能市场? 当我第一次接触OpenClaw时,最让我惊喜的不是它能操控鼠标键盘的能力,而是它背后那个充满可能性的技能市场。作为一个长期被重复性工作困扰…...
从一次“意外”发现flag说起:复盘uWSGI目录穿越漏洞(CVE-2018-7490)排查中的常见思维盲区
从"Not Found"到flag:uWSGI目录穿越漏洞实战思维全解析 当浏览器返回"Not Found"时,大多数人的第一反应是漏洞利用失败。但真正的安全测试往往始于这些看似失败的瞬间。去年在内部红队演练中,我遇到一个经典场景&#x…...
工业相机图像获取:RAW 图像如何保存和显示,附海康Basler堡盟相机代码
工业相机RAW图像保存显示,海康/Basler/堡盟代码直接抄 阅读提示:本文偏向工业视觉入门实操,避开晦涩理论,聚焦RAW图像的保存、显示落地方法,附带三大主流工业相机品牌的实测代码,适合视觉工程师、调试新手快…...
Jupyter Notebook内核崩溃?别急着重装!试试这个Anaconda环境修复方案
Jupyter Notebook内核崩溃?别急着重装!Anaconda环境修复全指南 当你正专注地编写代码,突然看到"内核似乎挂掉了,它很快将自动重启"的提示,那种挫败感我深有体会。作为数据科学工作者,Jupyter Not…...
VideoAgentTrek-ScreenFilter项目依赖管理:.NET生态下的客户端封装库开发
VideoAgentTrek-ScreenFilter项目依赖管理:.NET生态下的客户端封装库开发 最近在做一个视频处理相关的项目,需要频繁调用VideoAgentTrek-ScreenFilter的HTTP API。每次调用都得手动拼装HTTP请求、处理序列化、解析响应,代码里到处都是重复的…...
双指针-11. 盛最多水的容器
文章目录1.题解2.机考代码3.知识点讲解1.异向双指针力扣地址: 中等:11. 盛最多水的容器1.题解 class Solution {public int maxArea(int[] height) {int maxarea 0, l 0, r height.length - 1;while(l < r){maxarea Math.max(maxarea, Math.min(…...
数字古籍下载工具使用指南:从入门到精通
数字古籍下载工具使用指南:从入门到精通 【免费下载链接】bookget bookget 数字古籍图书下载工具 项目地址: https://gitcode.com/gh_mirrors/bo/bookget 数字古籍下载工具是一款专为古籍爱好者和研究者设计的资源获取软件,能够帮助用户高效检索、…...
OpenClaw飞书机器人速成:GLM-4.7-Flash对话触发与任务执行
OpenClaw飞书机器人速成:GLM-4.7-Flash对话触发与任务执行 1. 为什么选择OpenClaw飞书GLM组合? 去年夏天,当我第一次尝试用自然语言让AI帮我整理会议录音时,经历了整整三天的挫败——要么是云端API调用太贵,要么是本…...
显卡健康体检师:用memtest_vulkan给你的GPU做全面显存检测
显卡健康体检师:用memtest_vulkan给你的GPU做全面显存检测 【免费下载链接】memtest_vulkan Vulkan compute tool for testing video memory stability 项目地址: https://gitcode.com/gh_mirrors/me/memtest_vulkan 你是否曾经遇到过游戏突然崩溃、画面出现…...
华为S5700交换机Combo口配置踩坑实录:从光口不亮到链路闪断,我的排错全记录
华为S5700交换机Combo口故障排查手记:一位工程师的深夜排错实录 凌晨2:15,监控系统刺耳的告警声把我从半梦半醒中彻底拽了出来。核心交换机与接入层之间的GigabitEthernet 1/0/5接口状态像霓虹灯一样在UP/DOWN之间疯狂切换——这已经是本周第三次了。作为…...
