设计模式:抽象工厂
定义
抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。这种模式特别适用于处理产品族,但在不可能修改的情况下扩展产品族是困难的。
应用场景
抽象工厂模式通常在以下情况下使用:
- 当存在多个产品系列,且产品之间存在一定的关系时。
- 系统需要配置多个产品族中的一个产品族。
- 系统需要提供多个产品族的对象,而你希望在设计时不需要指定具体产品的类。
示例
以下是一个简单的Java示例,演示了抽象工厂模式的应用。在这个例子中,我们有两个产品族:Windows和MacOS,并且每个产品族都有两种产品:Button和Checkbox。
首先,我们定义产品接口和具体产品:
// Button接口
public interface Button {void paint();
}// Windows风格的Button
public class WinButton implements Button {@Overridepublic void paint() {System.out.println("Render a button in a Windows style.");}
}// MacOS风格的Button
public class MacButton implements Button {@Overridepublic void paint() {System.out.println("Render a button in a MacOS style.");}
}// Checkbox接口
public interface Checkbox {void paint();
}// Windows风格的Checkbox
public class WinCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Render a checkbox in a Windows style.");}
}// MacOS风格的Checkbox
public class MacCheckbox implements Checkbox {@Overridepublic void paint() {System.out.println("Render a checkbox in a MacOS style.");}
}
接下来,我们定义抽象工厂和具体工厂:
// 抽象工厂
public interface GUIFactory {Button createButton();Checkbox createCheckbox();
}// Windows工厂
public class WinFactory implements GUIFactory {@Overridepublic Button createButton() {return new WinButton();}@Overridepublic Checkbox createCheckbox() {return new WinCheckbox();}
}// MacOS工厂
public class MacFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic Checkbox createCheckbox() {return new MacCheckbox();}
}
最后,客户端代码可以这样使用抽象工厂来创建不同风格的UI元素:
public class Application {private Button button;private Checkbox checkbox;public Application(GUIFactory factory) {button = factory.createButton();checkbox = factory.createCheckbox();}public void paint() {button.paint();checkbox.paint();}
}public class Client {public static void main(String[] args) {GUIFactory factory;String osName = System.getProperty("os.name").toLowerCase();if (osName.contains("windows")) {factory = new WinFactory();} else {factory = new MacFactory();}Application app = new Application(factory);app.paint();}
}
原则间的权衡与冲突
抽象工厂模式遵守开闭原则,因为新增产品族时,无需修改已有代码,只需添加新的工厂和产品实现。同时,它也支持依赖倒置原则,因为客户端代码依赖于抽象接口,而不是具体实现。
然而,如果需要向现有产品族中添加新产品,可能需要修改工厂接口和所有实现类,这违反了开闭原则。
设计模式的局限性
抽象工厂模式的局限性主要体现在难以支持新产品的添加。每当添加一个新产品时,都需要更新抽象工厂及其所有子类,这会导致代码变得复杂,增加维护成本。
总结与建议
抽象工厂模式是一个强大的设计模式,适合用于产品族的创建。它提高了系统的可扩展性和可维护性,同时也隐藏了具体产品的实现细节。不过,设计者应该在产品族相对稳定,不太可能频繁变更时使用抽象工厂模式。对于经常变化的产品结构,考虑使用更灵活的模式可能更为合适,如工厂方法模式或者简单工厂模式。
相关文章:
设计模式:抽象工厂
定义 抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。这种模式特别适用于处理产品族,但在不可能修改的情况下扩展产品族是困难的。 应用场景 抽象工厂模式通…...
【环境搭建】ubuntu工作站搭建全流程(显卡4090)
安装ubuntu22.04系统 首先,先压缩windows分区,按住Win X快捷键,选择磁盘管理,压缩分区,压缩出新的分区用于安装ubuntu22.04 windows插入系统盘,点击重启,一直按F12,选择系统盘启动方式语言选择chinese–…...
蓝桥杯每日一题:有序分数(递归)
给定一个整数 N,请你求出所有分母小于或等于 N,大小在 [0,1] 范围内的最简分数,并按从小到大顺序依次输出。 例如,当 N5 时,所有满足条件的分数按顺序依次为: 0/1,1/5,1/4,1/3,2/5,12/,35,2/3,3/4,4/5,1/…...
SpringBoot学习之Kibana下载安装和启动(Mac版)(三十二)
一、简介 Kibana是一个开源的分析与可视化平台,设计出来用于和Elasticsearch一起使用的。你可以用kibana搜索、查看存放在Elasticsearch中的数据。Kibana与Elasticsearch的交互方式是各种不同的图表、表格、地图等,直观的展示数据,从而达到高级的数据分析与可视化的目的。 …...
Mac下Docker Desktop starting的解决方法
记录下自己在新增了一个新的容器后,Disk Size过大导致启动Docker Desktop会一直卡在Docker Desktop starting,并且重启无效的解决方法。该方法无需重新卸载,并且能保留原有的镜像和容器。 一、确认问题 首先确认Docker.raw大小以确认是否和笔…...
Leetcode面试经典150_Q80删除有序数组中的重复项 II
题目: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件…...
android 使用ollvm混淆so
使用到的工具 ndk 21.1.6352462(android studio上下载的)cmake 3.10.2.4988404(android studio上下载的)llvm-9.0.1llvm-mingw-20230130-msvcrt-x86_64.zipPython 3.11.5 环境配置 添加cmake mingw环境变量如下图: 编译 下载…...
Swift:在 Win10 上编程入门
访问 https://swift.org/download/ 找到 Windows 10:x86_64 下载 swift-5.10-RELEASE-windows10.exe 大约490MB 建议安装在 D:\Swift\ ,安装后大约占2.56GB 官网文档:https://www.swift.org/documentation/ 中文教程:The swift…...
Linux多进程通信(4)——消息队列从入门到实战!
Linux多进程通信总结——进程间通信看这一篇足够啦! 1.基本介绍 1)消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构,向消息队列中写数据,实际上是向这个数据结构中插入一个…...
[Flutter]导入singular_flutter_sdk后运行到Android报错
问题: 接入归因之前,flutter项目一起正常。接入归因之后,iOS正常Android有问题。 dependencies: # Singular归因singular_flutter_sdk: ^1.3.3 针对 Flutter 的 Singular SDK 集成指南 https://support.singular.net/hc/zh-cn/articles/…...
ChatGPT新手指南:如何用AI写出专业学术论文
ChatGPT无限次数:点击直达 ChatGPT新手指南:如何用AI写出专业学术论文 在当今信息爆炸的时代,人工智能技术的快速发展为我们提供了许多新的可能性。ChatGPT作为一种先进的自然语言处理技术,不仅能够进行对话和文本生成,还可以辅助…...
【ZZULIOJ】1047: 对数表(Java)
目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy code 题目描述 输入两个正整数m和n,输出m到n之间每个整数的自然对数。 输入 输入包括两个整数m和n(m<n),之间用一个空格隔开。 输出 每行输出一个整数及其对数,整数占4…...
thinkphp6使用阿里云SDK发送短信
使用composer安装sdk "alibabacloud/dysmsapi-20170525": "2.0.24"封装发送短信类 发送到的短信参数写在env文件里面的 #发送短信配置 [AliyunSms] AccessKeyId "" AccessKeySecret "" signName"" templateCode"&…...
file_get_contents(‘php://input‘); 这个postman要如何传参
在 Postman 中传递参数给 file_get_contents(php://input); 是通过请求的 Body 部分来实现的。使用 Postman 进行 API 接口测试时,可以按照以下步骤来传递参数: 打开 Postman 并创建一个新的请求。在请求的 URL 地址栏输入你的 API 地址。选择请求方法为…...
HDFS [MSST‘10] 论文阅读笔记
原论文:The Hadoop Distributed File System (MSST’10) HDFS关键技术要点概览 设计目标:HDFS旨在可靠地存储大型数据集,并以高带宽流式传输这些数据集到用户应用程序。它通过在大量服务器上分布存储和计算资源,使得资源可以随着需求的增长而扩展,同时保持经济高效。架构组…...
Feature Pyramid Networks for object detection
FPN 总述1.引言2.相关工作3. Feature Pyramid NetworksBottom-up pathwayTop-down pathway and lateral connections 4. 应用用于 RPN用于 Fast R-CNN 核心代码复现FPN网络结构ResNet Bottleneck完整代码 总述 下图中,蓝色边框表示的是特征图,边框越粗表…...
Linux下docker运行python
前言 本机开发环境众多,python版本都好多个,虽然可以通过conda管理多个虚拟环境,但还是不能像容器那样进行进程间的隔离。于是打算试下docker下运行python,而且生产环境很多时候也是用容器来跑应用,环境统一、方便扩容…...
MacOS下载和安装HomeBrew的详细教程
在MacOS上安装Homebrew的详细教程如下:(参考官网:macOS(或 Linux)缺失的软件包的管理器 — Homebrew) 步骤1:检查系统要求 确保你的MacOS版本至少为macOS Monterey (12) (or higher) 或更高版本…...
AI技术在金融领域/银行业的应用和风险
前言 随着科技的不断发展,人工智能(AI)技术已经在各行各业得到了广泛的应用,其中包括银行业。银行业作为经济的重要组成部分,一直在不断地探索和应用新技术,以提升服务效率、风险管理和客户体验。然而&…...
每日OJ题_两个数组dp⑤_力扣10. 正则表达式匹配
目录 力扣10. 正则表达式匹配 解析代码 力扣10. 正则表达式匹配 10. 正则表达式匹配 难度 困难 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个前面的那一个元素 所谓匹配,…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
是否存在路径(FIFOBB算法)
题目描述 一个具有 n 个顶点e条边的无向图,该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序,确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数,分别表示n 和 e 的值(1…...
面向无人机海岸带生态系统监测的语义分割基准数据集
描述:海岸带生态系统的监测是维护生态平衡和可持续发展的重要任务。语义分割技术在遥感影像中的应用为海岸带生态系统的精准监测提供了有效手段。然而,目前该领域仍面临一个挑战,即缺乏公开的专门面向海岸带生态系统的语义分割基准数据集。受…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决
20250607在荣品的PRO-RK3566开发板的Android13系统下实现长按开机之后出现插入适配器不会自动启动的问题的解决 2025/6/7 17:20 缘起: 1、根据RK809的DATASHEET,短按开机【100ms/500ms】/长按关机,长按关机。6s/8s/10s 我在网上找到的DATASHE…...
code-server安装使用,并配置frp反射域名访问
为什么使用 code-server是VSCode网页版开发软件,可以在浏览器访问编程,可以使用vscode中的插件。如果有自己的服务器,使用frp透传后,域名访问在线编程,使用方便,打开的服务端口不需要单独配置,可…...
