设计模式 - 抽象工厂模式
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快!
文章目录
- 引言
- 一、抽象工厂模式的基本概念
- 二、抽象工厂模式的实现
- 1. 定义抽象产品接口
- 2. 定义具体产品类
- 3. 定义抽象工厂接口
- 4. 定义具体工厂类
- 5. 客户端代码
- 6. Java 示例代码
- 三、抽象工厂模式的优点
- 四、抽象工厂模式的应用场景
- 五、抽象工厂模式的缺点
- 六、扩展抽象工厂模式
- 七、总结
引言
抽象工厂模式是一种创建型设计模式,它提供了一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。这种模式特别适用于需要创建一系列相关产品的情况,而且这些产品的具体实现可能会随着环境的不同而改变。本文将详细介绍抽象工厂模式的概念,并通过具体的Java代码示例来说明如何实现这一模式。
一、抽象工厂模式的基本概念
抽象工厂模式的主要参与者包括:
- AbstractFactory:声明一个用于创建一系列相关或相互依赖对象的接口。
- ConcreteFactory:实现了 AbstractFactory 接口,负责创建具体的产品对象。
- AbstractProduct:声明了产品对象的接口。
- ConcreteProduct:实现了 AbstractProduct 接口,是具体的产品对象。
二、抽象工厂模式的实现
接下来,我们将通过一个示例来详细了解抽象工厂模式的实现步骤。
1. 定义抽象产品接口
首先,定义抽象产品接口,这些接口将被具体产品实现:
// 抽象产品接口
public interface Button {void click();
}public interface Checkbox {void select();
}
2. 定义具体产品类
接下来,定义具体产品类,这些类实现了前面定义的抽象产品接口:
// 具体产品类
public class WindowsButton implements Button {@Overridepublic void click() {System.out.println("Windows Button clicked.");}
}public class WindowsCheckbox implements Checkbox {@Overridepublic void select() {System.out.println("Windows Checkbox selected.");}
}public class MacOSButton implements Button {@Overridepublic void click() {System.out.println("MacOS Button clicked.");}
}public class MacOSCheckbox implements Checkbox {@Overridepublic void select() {System.out.println("MacOS Checkbox selected.");}
}
3. 定义抽象工厂接口
定义抽象工厂接口,该接口声明了创建具体产品的工厂方法:
// 抽象工厂接口
public interface GUIFactory {Button createButton();Checkbox createCheckbox();
}
4. 定义具体工厂类
实现抽象工厂接口,具体工厂类负责创建对应的操作系统风格的用户界面组件:
// 具体工厂类
public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic Checkbox createCheckbox() {return new WindowsCheckbox();}
}public class MacOsFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacOSButton();}@Overridepublic Checkbox createCheckbox() {return new MacOSCheckbox();}
}
5. 客户端代码
客户端代码使用抽象工厂来创建产品族:
public class ClientApplication {private Button button;private Checkbox checkbox;public ClientApplication(GUIFactory factory) {button = factory.createButton();checkbox = factory.createCheckbox();}public void paint() {button.click();checkbox.select();}
}
6. Java 示例代码
创建客户端应用程序并使用抽象工厂创建产品族:
public class Main {public static void main(String[] args) {// 创建客户端应用程序ClientApplication windowsApp = new ClientApplication(new WindowsFactory());ClientApplication macOsApp = new ClientApplication(new MacOsFactory());// 使用 Windows 风格的界面System.out.println("Windows style UI:");windowsApp.paint();// 使用 MacOS 风格的界面System.out.println("\nMacOS style UI:");macOsApp.paint();}
}
三、抽象工厂模式的优点
- 封装变化:通过抽象工厂模式,可以很容易地更换产品族,而不需要修改客户端代码。
- 易于扩展:当需要添加新的产品族时,只需新增具体工厂和具体产品类即可。
- 高内聚低耦合:抽象工厂模式使得客户端与具体产品解耦,提高了系统的灵活性。
四、抽象工厂模式的应用场景
抽象工厂模式适用于以下情况:
- 产品族:当需要创建一系列相关或相互依赖的对象,但不必显式指定它们的具体类时。
- 多样性:当系统需要独立于平台和具体实现时,比如支持多种操作系统。
- 配置:当需要根据运行时的配置来选择适当的产品族时。
五、抽象工厂模式的缺点
- 复杂性:相比于简单工厂模式,抽象工厂模式引入了更多的类和接口,增加了系统的复杂性。
- 难以更改:一旦产品族被定义后,如果需要增加新的产品类型,则需要修改现有代码。
六、扩展抽象工厂模式
在实际应用中,可以通过以下方式扩展抽象工厂模式:
- 层次化抽象工厂:如果产品族本身也可以分类,可以创建多个层次的抽象工厂,每个层次负责创建不同类别的产品族。
- 参数化抽象工厂:允许客户端通过参数来指定具体工厂,从而在运行时动态选择产品族。
七、总结
通过本文的详细介绍和示例代码,相信你应该已经掌握了抽象工厂模式的基本实现细节及其在不同情况下的表现。抽象工厂模式是面向对象设计中一种非常有用的模式,特别是在需要创建一系列相关产品的情况下。在实际编程中,抽象工厂模式可以用于构建高度可配置和可扩展的系统,尤其是在需要支持多种不同类型的产品时。通过上述实现,你可以根据自己的需求进一步扩展和优化抽象工厂模式的应用。
在设计系统时,考虑到抽象工厂模式的灵活性和可扩展性,它可以成为创建一系列相关对象的理想选择。此外,它还提供了一种简洁的方式来应对系统需求的变化,使你的代码更加健壮和易于维护。
💝💝💝如有需要请大家订阅我的专栏【设计模式】哟!我会定期更新相关系列的文章
💝💝💝关注!关注!!请关注!!!请大家关注下博主,您的支持是我不断创作的最大动力!!!
❤️❤️❤️觉得有用的话点个赞 👍🏻 呗。
❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍
🔥🔥🔥Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
相关文章:
设计模式 - 抽象工厂模式
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快! 文章目录 引言一、抽象工…...
塔子哥选数字-阿里淘天2024笔试(codefun2000)
题目链接 塔子哥选数字-阿里淘天2024笔试(codefun2000) 题目内容 塔子哥有一个长为n的数组a。他定义一个数组的权值为:数组中不同的数字个数。 塔子哥希望从数组a中选出在个数子,使得这k个数字组成的数组权值最大,请你帮帮塔子哥。 输入描述…...

【leetcode】杨辉三角(Java语言描述)
杨辉三角 给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例 2: 输入: numRows 1 输出: [[1]] …...

Vue - 关于vue-kinesis 移动动画组件
Vue - 关于vue-kinesis 移动动画组件 vue-kinesis可以根据鼠标移动或滚动条来控制元素动画的动画效果;除此之外,vue-kinesis 还可以设置音频文件,根据音频频率来控制动画的跳动效果。 一、安装vue-kinesis Vue2版本: 1.安装 …...

leetCode- - - 链表
目录 1.反转链表(leetcode206) 2. 链表内指定区间反转(leetcode92) 3.链表中的节点每k个一组翻转(leetcode25) 4.合并两个排序的链表(leetcode21) 5.链表的中间节点(…...

Ashok:一款多功能开源网络侦查OSINT工具
关于Ashok Ashok是一款多功能开源网络侦查公开资源情报OSINT工具,该工具可谓是OSINT领域中的瑞士军刀,广大研究人员可以使用该工具轻松完成网络侦查任务。 侦察是渗透测试的第一阶段,这意味着在计划任何实际攻击之前收集信息。因此ÿ…...

没有获取淘宝API的资质怎么获取淘宝数据
淘宝是头部电商平台之一,每个自研商家或电商软件服务商想要开发电商管理功能模板就少不了要对接淘宝API。淘宝API是在淘宝开放平台提供的,自研商家和软件服务商接入淘宝开放平台需要经过一系列审核和申请流程,要求资质和相关资料符合对应的要…...

SQL手工注入
目录 1.判断是否存在sql注入点 1.1我们在地址栏中输入?id1 1.2我们在地址栏中输入?id-- 2.联合查询 2.1首先知道表格有几列,如果报错就是超过列数,如果显示正常就是没有超出列数。 2.2爆出显示位,就是看看表格里面哪一列是在页面显示…...

【SQL】大的国家
目录 题目 分析 代码 题目 World表: ---------------------- | Column Name | Type | ---------------------- | name | varchar | | continent | varchar | | area | int | | population | int | | gdp | bigint | ----…...

8月5日学习笔记 glibc安装与安全用户角色权限
一,glibc安装 https://www.mysql.com/ 官⽹ https://downloads.mysql.com/archives/community/ https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.33-li nux-glibc2.12-x86_64.tar 安装步骤 1.安装依赖库 [rootlocalhost ~]# yum list installed |g…...
DrissionPage 一个替代selenium的pip --- 一个可以接管正在运行的chrome包
DrissionPage 一个替代selenium的pip包,持续更新 1、加载内容,并接管chrome浏览器 from DrissionPage import ChromiumPage, ChromiumOptions page ChromiumPage(addr_or_opts127.0.0.1:9222) print(page.title)ul page.eles(idform-submit) for i i…...

爬虫入门--了解相关工具
目录 1.爬虫与python 2.第一个爬虫 3.web请求的全过程 3.1服务器渲染 3.2前端JS渲染 4.浏览器工具 4.1Elements 4.2Console 4.3Source 4.4network(重点) 5.小结 1.爬虫与python 首先我们要知道,爬虫一定要用Python么? 非也~…...
django项目中通用的分页组件
文章目录 分页组件pager组件代码 分页组件 应用分页组件,需要以下两个步骤: 视图函数中:(先获取queryset,将request和queryset传入分页组件对象中,得到生成的html标签) def customer_list(requ…...

想实现ubuntu搭建sqli-labs靶场
目录 首先前期的nginx和php部署完成编辑编辑 Xftp导入sqli-labs 遇到了的问题 它提示我们请检查db-creds.inc 去尝试解决这个问题 尝试修改MySQL root密码 修改db-creds.inc配置 再次尝试依旧失败 思考:会不会是MySQL版本过高的原因 重新下载MySQL5.7.…...
tp8 按日期分组查出数据
1.如果数据库里时间字段都是时间戳,使用mysql中的from_unixtime()函数 field("from_unixtime(create_time,%Y-%m-%d) as time,group_concat(id)")->group(time)->select()2. 如果数据库是普通的日期格式(如2024-01-02 01:23:50)&#x…...
单例模式(懒汉模式,饿汉模式)
单例的饿汉模式:在主函数未调用之前该单例就已经存在了,所以不存在线程安全的问题。 class Singleton { private: Singleton(){} public:static Singleton s1;static Singleton* GetInstance(){return &s1;}Singleton(const Singleton&) delet…...

【Qt】Item Widgets 多元素控件
Qt中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView 上述控件分为Widget和View,其区别如下: 以QTableWidget和QTableView为例 QTableView是基于MVC(Model-View-Controller)设计的控件。QTableView自身…...

sharded_inference_engine:MLXDynamicShardInferenceEngine;step
目录 sharded_inference_engine:MLXDynamicShardInferenceEngine 类属性 方法 __init__(self) async def infer_prompt(self, shard: Shard, prompt: str, inference_state: Optional[str] = None) -> (np.ndarray, str, bool) async def infer_tensor(self, shard: …...

JAVA开发学习-day21
JAVA开发学习-day21 1. 删除表单数据 根据ElementUI的官方组件指南,为表单每列的数据添加删除按钮 <el-table :data"tableData" style"width: 100%"><el-table-column prop"id" label"ID" width"180"…...

Python的安装环境以及应用
1.环境python2,Python 最新安装3.12可以使用源码安装 查看安装包 [rootpython001 ~]# yum list installed | grep epel 3[rootpython001 ~]# yum list installed | grep python [rootpython001 ~]# yum -y install python3 安装python3 查看版本 [root…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

云安全与网络安全:核心区别与协同作用解析
在数字化转型的浪潮中,云安全与网络安全作为信息安全的两大支柱,常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异,并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全:聚焦于保…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
Django RBAC项目后端实战 - 03 DRF权限控制实现
项目背景 在上一篇文章中,我们完成了JWT认证系统的集成。本篇文章将实现基于Redis的RBAC权限控制系统,为系统提供细粒度的权限控制。 开发目标 实现基于Redis的权限缓存机制开发DRF权限控制类实现权限管理API配置权限白名单 前置配置 在开始开发权限…...