结合简单工厂和工厂方法模式:实现灵活的对象创建
前言
在软件开发过程中,创建对象的方式直接影响代码的灵活性和可维护性。设计模式提供了一种解决复杂问题的方法,其中简单工厂模式和工厂方法模式是两种常用的创建型模式。在这篇文章中,我们将结合这两种模式,通过一个实际案例,展示如何有效地创建和管理对象。
背景与问题描述
假设我们正在开发一个跨平台的应用程序,需要支持不同类型的组件(例如按钮和窗口),而且要根据不同的配置来决定使用哪种平台实现。我们希望通过相同的接口来使用它们,从而简化代码和提高灵活性。
问题
直接在客户端代码中使用 new 关键字来创建不同平台的组件会导致代码耦合度高,不易扩展。如果未来需要支持新的平台(例如 Linux),就必须修改客户端代码,这违反了开闭原则。
解决方案
我们可以结合使用简单工厂模式和工厂方法模式。通过简单工厂来选择具体的工厂类,然后由具体工厂类通过工厂方法创建具体的产品对象。
设计与实现
产品接口
首先,定义按钮和窗口的接口。
// 按钮接口
public interface Button {void render();void onClick();
}// 窗口接口
public interface Window {void render();
}
具体产品类
接下来,实现不同平台的具体产品类。
// Windows 按钮
public class WindowsButton implements Button {public void render() {System.out.println("Render a button in Windows style.");}public void onClick() {System.out.println("Handle button click in Windows style.");}
}// Mac 按钮
public class MacButton implements Button {public void render() {System.out.println("Render a button in macOS style.");}public void onClick() {System.out.println("Handle button click in macOS style.");}
}// Windows 窗口
public class WindowsWindow implements Window {public void render() {System.out.println("Render a window in Windows style.");}
}// Mac 窗口
public class MacWindow implements Window {public void render() {System.out.println("Render a window in macOS style.");}
}
抽象工厂类
定义创建按钮和窗口的抽象工厂类。
// 抽象工厂类
public abstract class GUIFactory {public abstract Button createButton();public abstract Window createWindow();
}
具体工厂类
实现不同平台的具体工厂类。
// Windows 工厂
public class WindowsFactory extends GUIFactory {public Button createButton() {return new WindowsButton();}public Window createWindow() {return new WindowsWindow();}
}// Mac 工厂
public class MacFactory extends GUIFactory {public Button createButton() {return new MacButton();}public Window createWindow() {return new MacWindow();}
}
简单工厂类
使用简单工厂类来选择具体的工厂。
public class GUIFactorySimpleFactory {public static GUIFactory getFactory(String osType) {if (osType.equalsIgnoreCase("Windows")) {return new WindowsFactory();} else if (osType.equalsIgnoreCase("Mac")) {return new MacFactory();} else {throw new IllegalArgumentException("Unknown OS type.");}}
}
客户端代码
在客户端代码中使用简单工厂选择具体工厂,然后通过工厂方法创建产品对象。
public class Application {private Button button;private Window window;public Application(GUIFactory factory) {button = factory.createButton();window = factory.createWindow();}public void render() {button.render();window.render();}public static void main(String[] args) {// 选择操作系统类型String osType = "Windows"; // 这个可以根据配置文件或运行时参数来决定// 使用简单工厂获取具体工厂GUIFactory factory = GUIFactorySimpleFactory.getFactory(osType);// 使用工厂方法创建具体产品Application app = new Application(factory);app.render();}
}
总结
通过将简单工厂和工厂方法结合使用,我们可以实现更灵活和可扩展的对象创建方式。在这个例子中,简单工厂用于选择具体的工厂,而具体工厂通过工厂方法来创建产品对象。这种组合方式不仅降低了客户端代码与具体类之间的耦合度,还使得系统更易于扩展和维护。
希望这个例子能帮助你更好地理解简单工厂和工厂方法的结合使用。如果你觉得这篇文章对你有帮助,请给我点个关注和赞!谢谢!
相关文章:
结合简单工厂和工厂方法模式:实现灵活的对象创建
前言 在软件开发过程中,创建对象的方式直接影响代码的灵活性和可维护性。设计模式提供了一种解决复杂问题的方法,其中简单工厂模式和工厂方法模式是两种常用的创建型模式。在这篇文章中,我们将结合这两种模式,通过一个实际案例&a…...
网抑云特殊版,登录即永久
前言 今天分享一款特殊版本的音乐软件,相信大家在听网抑云的时候会有两大烦恼, 一是歌曲需要开通VIP才可以收听,不管怎么说也是国内厂商普遍操作 但是第二种烦恼你万万想不到的是,开通了会员后,惊奇的发现ÿ…...
Kotlin 实战小记:No-Arg 引用解决 No constructor found的问题
一、问题 新的项目试用一下kotlin, 调用数据库查询数据的时候报了这个问题:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: No constructor found in com.neusoft.collect.entity.cm.CmRoom matc…...
HTML(5)——列表表格
列表 无序列表 作用:布局排列整齐的不需要规定顺序的区域。 标签:ul嵌套il,ul是无序列表,li是列表条目 注:ul标签只能包裹li标签,li标签可以包含任何内容 有序列表 作用:布局排列整齐的需…...
FreeBSD通过CBSD管理低资源容器jail来安装Ubuntu子系统实践
简介 FreeBSD、CBSD、Jail和Ubuntu,四者的组合方案可以说是强强联合,极具性价比和竞争力!同时安装简单方便,整体方案非常先进。 CBSD是为FreeBSD jail子系统、bhyve、QEMU/NVMM和Xen编写的管理层。该项目定位为一个综合解决方案…...
SpringCloud总结(springcloud alibaba)
目录 版本说明(很重要) springcloud alibaba对应组件版本说明 简述 spring cloud albaba 几大模块 周会讨论 - spring cloud alibaba每周都会有周会讨论,社区活跃 spring cloud alibaba官网 注册配置中心 简单介绍 nacos 步骤 示例代码 依赖…...
轻轻松松上手的LangChain学习说明书
本文为笔者学习LangChain时对官方文档以及一系列资料进行一些总结~覆盖对Langchain的核心六大模块的理解与核心使用方法,全文篇幅较长,共计50000字,可先码住辅助用于学习Langchain。 一、Langchain是什么? 如今各类AI…...
全面对比与选择指南:Milvus、PGVector、Zilliz及其他向量数据库
本文全面探讨了Milvus、PGVector、Zilliz等向量数据库的特性、性能、应用场景及选型建议,通过详细的对比分析,帮助开发者和架构师根据具体需求选择最合适的向量数据库解决方案。 文章目录 向量数据库概述向量数据库的关键功能向量数据库的扩展和选择向量…...
svm 超参数
https://www.cnblogs.com/ChevisZhang/p/12932674.html https://wenku.baidu.com/view/b8a2c73cfd4733687e21af45b307e87100f6f861.html?wkts1718332423081&bdQuerysvm%E7%9A%84%E8%B6%85%E5%8F%82%E6%95%B0 用交叉验证找到最好的参数 C 和γ 。使用 RBF 核时,…...
001-基于Sklearn的机器学习入门:Sklearn库基本功能和标准数据集
本节将介绍Sklearn库基本功能,以及其自带的几个标准数据集的调用方法。本节是学习后面内容的基础,如果您已经对本节内容相当熟悉,可跳过本节内容。 1.1 Sklearn库基本功能 的 1.2 Sklearn库标准数据集 Sklearn自带许多标准数据集ÿ…...
充电学习—7、BC1.2 PD协议
BC1.2(battery charging)充电端口识别机制: SDP、CDP、DCP 1、VBUS detect:vbus检测 PD(portable device,便携式设备)中有个检测VBUS是否有效的电路,电路有个参考值,高…...
技术点梳理0618
ann建库,分布式建库,性能优化,precision recall参数优化 hnsw,图索引 1. build a)确定层:类似跳表思路建立多层,对每一个插入的节点,random层号l,从图的起始点search_…...
石英砂酸洗提纯方法和工艺
石英砂酸洗提纯方法和工艺是石英砂加工中至关重要的一个环节,其目的是通过化学手段去除石英砂中的杂质,提升其纯度。以下将详细介绍石英砂酸洗提纯的方法和工艺,以便更好地理解和应用这一技术。 一、概述 石英砂酸洗提纯主要是利用酸液对石英…...
linux安装dgl
1.DGL官网、选择与自己cuda、python版本匹配的dgl的whl文件CUDA11.8、python10并下载 2.用pip install运行 pip install /home/u2023170749/download/dgl-2.2.0cu118-cp310-cp310-manylinux1_x86_64.whl或者直接安装https://blog.csdn.net/weixin_44017989/article/details/13…...
【SAP-ABAP】-权限批导-批量给某个角色导入事务码权限
需求:SAP期初上线的时候,业务顾问经常会遇到批量创建角色和分配角色权限的情况 岗位需求:一般是业务顾问定义权限,BASIS进行后期运维,今天讲两个批导功能,方便期初上线 主要函数:PRGN_READ_ROLE…...
异常处理总结
自定义异常 系统中的异常可以分为我们能预知的异常和未知的系统异常,对于我们能预知的异常如空值判断,用户名错误,密码错误等异常我们需要返回客户端,对于系统内部异常如SQL语法错误,参数格式转换错误等需要统一包…...
大模型日报2024-06-18
大模型日报 2024-06-18 大模型资讯 大模型产品 Olvy 3.0:AI加速客户反馈分析 摘要: Olvy 3.0推出AI自动监听和智能标签功能,通过Google Meet集成轻松提取洞察,贴近客户,激发同理心。 PlantIdentify-免费植物识别应用 摘要: PlantI…...
NumPy 双曲函数与集合操作详解
NumPy 双曲函数 NumPy 提供了 sinh()、cosh() 和 tanh() 等 ufunc,它们接受弧度值并生成相应的双曲正弦、双曲余弦和双曲正切值。 示例: import numpy as npx np.sinh(np.pi/2)print(x)示例 找到数组 arr 中所有值的双曲余弦值: import…...
ABSD-系统架构师(十三)
1、CDN和反向代理的基本原理都是()。 A缓存 B负载均衡 C路由转发 DNAT转发 答案:A 2、(必考)在ABSD(基于架构的软件开发)方法中,顶层被分解为()ÿ…...
PLC通过Profibus协议转Modbus协议网关接LED大屏通讯
一、背景 Modbus协议和Profibus协议是两种常用于工业控制系统的通信协议,它们在自动化领域中起着重要的作用。Modbus是一种串行通信协议,被广泛应用于各种设备之间的通信,如传感器、执行器、PLC等。而Profibus则是一种现场总线通信协议&…...
设计程序统计共享单车使用分布数据,优化投放点位,解决市民短途出行找不到车辆出行难题。
构建一个共享单车使用分布统计与投放点位优化的商务智能示例项目,去营销化、中立化,仅用于学习与工程实践参考。一、实际应用场景描述在城市短途出行场景中,共享单车已成为重要补充:- 覆盖公交、地铁“最后一公里”- 解决 1–3 公…...
RK3568开发板Android 11系统移植实战:从内核驱动到HAL适配
1. 项目概述与学习路径规划拿到一块像迅为iTOP-RK3568这样的开发板,想把最新的Android 11系统跑起来,这个想法听起来挺酷,但很多朋友一看到“系统移植”四个字就有点发怵,感觉这是大神才能玩转的领域。其实,只要你熟悉…...
PyTorch实战:手写Sobel与Laplace算子实现图像边缘检测
1. 图像边缘检测与卷积算子基础 第一次接触图像处理时,我对"边缘检测"这个概念特别好奇。简单来说,边缘就是图像中物体轮廓或纹理变化明显的区域。想象一下用铅笔描边一幅画的过程,边缘检测就是让计算机自动完成这个工作。 为什么边…...
基于RAG的智能招聘引擎:技术原理、实现与应用
1. 项目概述:一个面向人才招聘的智能RAG引擎最近在GitHub上看到一个挺有意思的项目,叫talent-rag-engine。光看名字,就能猜到个大概——这是一个专门为人才招聘场景设计的检索增强生成引擎。RAG(Retrieval-Augmented Generation&a…...
从ASCII到机器码:深入解析HEX文件的结构与校验机制
1. HEX文件的前世今生:从ASCII到机器码的桥梁 第一次接触HEX文件时,我也被那一串串看似毫无规律的十六进制字符搞得一头雾水。直到后来在嵌入式开发中频繁使用HEX文件进行固件升级,才真正理解了这个"翻译官"的重要性。HEX文件本质上…...
如何3分钟精准定位Windows热键冲突:Hotkey Detective深度技术解析
如何3分钟精准定位Windows热键冲突:Hotkey Detective深度技术解析 【免费下载链接】hotkey-detective A small program for investigating stolen key combinations under Windows 7 and later. 项目地址: https://gitcode.com/gh_mirrors/ho/hotkey-detective …...
数据清洗实战:解锁混乱数据,构建高效企业集成管道
1. 项目概述与核心价值 最近在和一些做企业级应用集成的朋友聊天,发现一个挺有意思的痛点:很多系统在对接时,数据格式五花八门,尤其是那些历史包袱重的老系统,传过来的数据经常是“拧巴”着的。比如,一个本…...
3大核心优势:QModMaster如何成为工业通信调试的必备利器
3大核心优势:QModMaster如何成为工业通信调试的必备利器 【免费下载链接】qModbusMaster Fork of QModMaster (https://sourceforge.net/p/qmodmaster/code/ci/default/tree/) 项目地址: https://gitcode.com/gh_mirrors/qm/qModbusMaster 你是否曾在调试工业…...
基于Council框架的多智能体协作:构建专家委员会式AI决策系统
1. 项目概述:一个智能化的团队决策引擎最近在开源社区里看到一个挺有意思的项目,叫“Cat-tj/council-tj”。这个名字乍一看有点抽象,但拆开来看,“Council”在英文里是“议会”或“委员会”的意思,而“tj”通常是“Tav…...
Armbian重置前的数据保卫战——备份与迁移的5层防护策略
备份就像买保险——平时觉得麻烦,出事时觉得买少了。 引言:那个让我彻夜未眠的晚上 凌晨三点,我的香橙派突然失联了。 SSH连不上,ping不通,插显示器一看——文件系统只读,内核panic。前一天刚折腾完Docker网络配置,手贱改了个内核参数,重启后直接翻车。 那一刻,我脑…...
