设计模式三:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式来创建一系列相关或相互依赖的对象,而无需指定具体实现类。
在软件开发中,有时候需要根据不同的条件或环境来创建一组相关的对象。抽象工厂模式将对象的创建逻辑封装在一个抽象工厂接口中,该接口声明了一系列用于创建不同类型对象的方法。具体的工厂类实现了这个接口,每个具体工厂类负责创建一组相关的对象。
通过使用抽象工厂模式,我们可以达到以下几个目标:
将客户端代码与具体产品的实现细节解耦,客户端只需要知道抽象工厂以及抽象产品的接口,而不需要关心具体的实现类。
提供一种扩展机制,当需要增加新的产品族时,只需要添加新的具体工厂类和具体产品类即可,而不需要修改已有的代码。
保持创建一组相关对象的一致性,确保所有创建出的对象都是相互匹配并且可以协同工作的。
抽象工厂模式适用于以下场景:
当需要创建一组相关的产品对象,并且这些产品对象之间有一定的约束关系时,可以使用抽象工厂模式。该模式保证了创建出来的产品对象是相互匹配并且可以协同工作的。
当系统需要独立于其产品的创建、组合和表示时,可以使用抽象工厂模式。通过使用抽象工厂模式,可以将产品的实现细节与客户端代码分离开来,使得客户端代码更加灵活和可维护。
当希望通过切换具体工厂类来改变整个产品族的构成时,可以使用抽象工厂模式。抽象工厂模式可以将产品的创建从客户端代码中解耦出来,使得系统更易于扩展和演化。
当需要指定创建对象的具体工厂时,可以使用抽象工厂模式。通过向抽象工厂提供一个参数,即可得到相应的具体工厂,然后通过具体工厂来创建所需的产品对象。
抽象工厂的具体实践
抽象工厂模式是一种创建型设计模式,它通过定义一个接口或抽象类作为工厂的基础,并在该接口或抽象类中声明用于创建不同类型产品对象的方法。具体的工厂类实现这个接口或抽象类,并按照特定规则实现产品对象的创建逻辑。
下面是一个简单的抽象工厂模式的代码示例:
// 抽象产品A
interface ProductA {void operation();
}// 具体产品A1
class ConcreteProductA1 implements ProductA {@Overridepublic void operation() {System.out.println("Concrete Product A1");}
}// 具体产品A2
class ConcreteProductA2 implements ProductA {@Overridepublic void operation() {System.out.println("Concrete Product A2");}
}// 抽象产品B
interface ProductB {void operation();
}// 具体产品B1
class ConcreteProductB1 implements ProductB {@Overridepublic void operation() {System.out.println("Concrete Product B1");}
}// 具体产品B2
class ConcreteProductB2 implements ProductB {@Overridepublic void operation() {System.out.println("Concrete Product B2");}
}// 抽象工厂
interface AbstractFactory {ProductA createProductA();ProductB createProductB();
}// 具体工厂1,负责创建具体产品系列1
class ConcreteFactory1 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA1();}@Overridepublic ProductB createProductB() {return new ConcreteProductB1();}
}// 具体工厂2,负责创建具体产品系列2
class ConcreteFactory2 implements AbstractFactory {@Overridepublic ProductA createProductA() {return new ConcreteProductA2();}@Overridepublic ProductB createProductB() {return new ConcreteProductB2();}
}// 客户端通过抽象工厂接口使用产品
public class Client {private ProductA productA;private ProductB productB;public Client(AbstractFactory factory) {this.productA = factory.createProductA();this.productB = factory.createProductB();}public void operation() {productA.operation();productB.operation();}public static void main(String[] args) {AbstractFactory factory1 = new ConcreteFactory1();Client client1 = new Client(factory1);client1.operation();AbstractFactory factory2 = new ConcreteFactory2();Client client2 = new Client(factory2);client2.operation();}
}
以上示例中,我们定义了两个产品族(ProductA和ProductB),每个产品族都有两个具体产品。抽象工厂(AbstractFactory)定义了创建产品的接口,具体工厂(ConcreteFactory1和ConcreteFactory2)实现了抽象工厂接口,并根据具体需求分别创建了不同的产品组合。
在客户端(Client)代码中,我们选择了要使用的具体工厂,然后通过该工厂创建产品并进行操作。
抽象工厂模式的优缺点
提供了一种易于扩展的方式来创建一组相关或依赖的对象。通过添加新的具体工厂和产品类,可以很容易地扩展抽象工厂模式。
客户端代码与具体类解耦。由于客户端只依赖于抽象类型,因此可以轻松地切换不同的工厂实现,从而改变创建的对象家族。
可以确保创建的产品是相互匹配的。由于抽象工厂负责创建一组相关的对象,因此可以保证这些对象之间的兼容性和一致性。
缺点:
增加了系统的复杂性。引入抽象工厂模式会增加额外的抽象层次,可能会导致系统更难理解和维护。
难以支持新种类的产品。当需要支持新的产品家族时,需要修改抽象工厂的接口以及所有具体工厂的实现,这可能会对现有代码产生一定的影响。
不利于单一职责原则。抽象工厂模式的具体工厂通常会负责创建一组相关或依赖的产品,这可能违反了单一职责原则。
综上所述,抽象工厂模式在某些情况下是有用的,特别是当需要创建一组相关对象时。但是,在使用抽象工厂模式之前,需要权衡其优点和缺点,并考虑是否适合特定的应用场景。
相关文章:
设计模式三:抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种方式来创建一系列相关或相互依赖的对象,而无需指定具体实现类。 在软件开发中,有时候需要根据不同的条件或环境来创建一组相关的对象。抽象工…...

Linux用户权限问题详解
Linux用户权限问题详解 【一】Linux权限的概念(1)用户类型(2)如何切换用户(3)用户相关的一些命令 【二】Linux文件权限管理(1)文件访问者的分类(2)文件类型和…...

flask中的session介绍
flask中的session介绍 在Flask中,session是一个用于存储特定用户会话数据的字典对象。它在不同请求之间保存数据。它通过在客户端设置一个签名的cookie,将所有的会话数据存储在客户端。以下是如何在Flask应用中使用session的基本步骤: 首先…...

记录联想拯救者R720重装系统
文章目录 bios里找不到U盘启动项2023.7.23重装系统后数据记录C盘内存修改默认AppData的路径(亲测,没用) bios里找不到U盘启动项 制作好启动盘后,开机按F2进入bios后,找不到U盘启动项,如下图所示࿱…...

Spring Alibaba Sentinel实现集群限流demo
1.背景 1.什么是单机限流? 小伙伴们或许遇到过下图这样的限流配置 又或者是这样的Nacos动态配置限流规则: 以上这些是什么限流?没错,就是单机限流,那么单机限流有什么弊端呢? 假设我们集群部署3台机器&a…...
102、SOA、分布式、微服务之间有什么关系和区别?
SOA、分布式、微服务之间有什么关系和区别? 分布式架构是指将单体架构中的各个部分拆分,然后部署到不同的机器或进程中去,SOA和微服务基本上都是分布式架构师SOA是一种面向服务的架构,系统的所有服务都注册在总线上,当调用服务时…...

Ubuntu 20.04下的录屏与视频剪辑软件
ubuntu20.04下的录屏与视频剪辑 一、录屏软件SimpleScreenRecorder安装与使用 1、安装 2、设置录制窗口参数 3、开始录制 二、视频剪辑软件kdenlive的安装 1、安装 2、启动 一、录屏软件SimpleScreenRecorder安装与使用 1、安装 (1)直接在终端输入以下命…...
面试题 -- iOS数据存储
文章目录 一、如果后期需要增加数据库中的字段怎么实现,如果不使用CoreData呢?二、SQLite 数据存储是怎么用?三、简单描述下客户端的缓存机制?四、实现过多线程的Core Data 么?NSPersistentStoreCoordinator࿰…...
spring复习:(51)environment、systemProperties、systemEnvironment三个bean是在哪里被添加到容器的?
一、主类: package cn.edu.tju.study.service.anno;import cn.edu.tju.study.service.anno.config.MyConfig; import cn.edu.tju.study.service.anno.domain.Person; import com.sun.javafx.runtime.SystemProperties; import org.springframework.context.annotat…...

element ui 上传控件携带参数到后端
1.携带固定参数: 2.携带不固定参数: <el-row> <el-col :span"24"> <el-upload :multiple"false" :show-file-list"false" :on-success"f_h…...
scrapy分布式+指纹去重原理
1,指纹去重原理存在于 scrapy.util.requests 里面 需要安装的包 pip install scrapy-redis-cluster # 安装模块 pip install scrapy-redis-cluster0.4 # 安装模块时指定版本 pip install --upgrade scrapy-redis-cluster # 升级模块版本 2,setting配置 …...

FileHub使用教程:Github Token获取步骤,使用快人一步
FileHub介绍 filehub是我开发的一个免费文件存储软件,可存万物。软件仓库:GitHub - Sjj1024/s-hub: 一个使用github作为资源存储的软件 软件下载地址:。有问题可以留言或者提Issue, 使用第一步:获取Github Token 使…...

嵌入式开发:单片机嵌入式Linux学习路径
SOC(System on a Chip)的本质区别在于架构和功能。低端SOC如基于Cortex-M架构的芯片,如STM32和NXP LPC1xxx系列,不具备MMU(Memory Management Unit),适用于轻量级实时操作系统如uCOS和FreeRTOS。…...
Libvirt的virsh工具常用命令
在使用Libvirt的virsh工具时,以下是常见的一些命令: 连接到Hypervisor: virsh -c <URI>:连接到指定的Hypervisor,例如 virsh -c qemu:///system 连接到本地的QEMU/KVM Hypervisor。 虚拟机管理: list…...
高斯消元解异或方程组写法
高斯约旦消元解异或方程组 for(int j1;j<n;j){for(int ij1;i<n;i)if(a[i][j]){swap(a[i],a[j]);break;}if(!a[i][i]){if(a[i][n1])//no...else ...//mul}for(int i1;i<n;i)if(i!j&&a[i][j])for(int kj;k<n1;k)a[i][k]^a[j][k];}正常高斯消元法 int r1;for…...

前端 mock 数据的几种方式
目录 接口demo Better-mock just mock koa webpack Charles 总结 具体需求开发前,后端往往只提供接口文档,对于前端,最简单的方式就是把想要的数据写死在代码里进行开发,但这样的坏处就是和后端联调前还需要再把写死的数据…...
【GO】go语言入门实战 —— 猜数字游戏
文章目录 程序介绍设置随机数读取用户输入实现判断逻辑实现游戏循环完整代码 程序介绍 首先生成一个介于1~100之间的随机数,然后提示玩家输入数字,并告诉玩家是猜对了还是猜错了,如果对了程序就结束,如果错了就提醒玩家是大了还是…...

opencv-25 图像几何变换04- 透视 cv2.warpPerspective()
什么是透视? 透视是一种几何学概念,用于描述在三维空间中观察物体时,由于视角的不同而产生的变形效果。在现实世界中,当我们从不同的角度或位置观察物体时,它们会呈现出不同的形状和大小。这种现象被称为透视效果。 透…...

视频讲解Codeforces Round 887 (Div. 2)(A--C)
文章目录 A. Desorting1、板书2、代码 B. Fibonaccharsis1、板书2、代码 C. Ntarsis Set1、板书2、代码 视频讲解Codeforces Round 887 (Div. 2)(A–C) A. Desorting 1、板书 2、代码 #include<bits/stdc.h> #define endl \n #define INF 0x3f…...

【团队协作开发】将Gitee项目导入到本地IDEA中出现根目录不完整的问题解决(已解决)
前言:在团队协作开发过程中,通常我们的Gitee完整项目中会包含很多内容:后端代码、前端代码、项目结构图、项目文档等一系列资产。 将Gitee项目导入到本地IDEA中,通常会出现根目录不完整的问题。这是因为项目里面包含了后端代码、前…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...

CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...