抽象工厂设计模式是什么?什么是 Abstract Factory 抽象工厂设计模式?Python 抽象工厂设计模式示例代码

什么是 Abstract Factory 抽象工厂设计模式?

抽象工厂设计模式是一种创建型设计模式,旨在提供一个创建一系列相关或相互依赖对象的接口,而无需指定其具体类。它允许客户端使用抽象的接口创建一组相关对象,而无需关注实际的对象实现。

在这里插入图片描述

主要角色:

  1. 抽象工厂(Abstract Factory): 定义了创建一组相关对象的接口,包括多个工厂方法用于创建不同类别的对象。

  2. 具体工厂(Concrete Factory): 实现了抽象工厂接口,负责创建一组具体的对象。

  3. 抽象产品(Abstract Product): 定义了一组产品对象的接口,由抽象工厂的工厂方法创建。

  4. 具体产品(Concrete Product): 实现了抽象产品接口的具体对象,由具体工厂的工厂方法创建。

在这里插入图片描述

工作流程:

  1. 定义抽象工厂接口: 定义一组创建对象的抽象方法,每个方法用于创建特定类别的对象。

  2. 创建具体工厂类: 实现抽象工厂接口,针对不同的对象族创建具体产品。

  3. 定义抽象产品接口: 定义一组产品对象的抽象方法。

  4. 创建具体产品类: 实现抽象产品接口,提供特定对象族的具体产品。

  5. 客户端使用抽象工厂: 通过抽象工厂接口创建一组相关的对象。

抽象工厂设计模式的优缺点如下:

优点:

  1. 产品族一致性: 抽象工厂能够确保相关或依赖的产品族一起工作,保证了产品的一致性和兼容性。

  2. 高层模块解耦: 客户端代码通过抽象接口与具体工厂交互,无需关注具体产品的实现细节,实现了高层模块与具体实现的解耦。

  3. 灵活性: 可以轻松替换具体工厂来改变整个产品族的行为,满足不同的业务需求。

  4. 符合开闭原则: 当需要增加新的产品族时,不需要修改已有代码,只需添加新的具体工厂即可,符合开闭原则。

缺点:

  1. 复杂性增加: 随着产品族和产品等级结构的增多,抽象工厂模式会导致类的数量急剧增加,使得系统变得复杂。

  2. 扩展困难: 增加新的产品族或产品等级结构会导致抽象工厂及其所有子类的修改,扩展性有限,容易导致代码膨胀。

  3. 单一职责原则问题: 当产品族较多时,具体工厂可能需要负责创建多个产品,违反了单一职责原则。

  4. 不易扩展新品种: 当需要添加新的产品品种时,要修改所有的具体工厂类,不够灵活。

综上所述,抽象工厂模式能够提供产品族一致性、高层模块解耦、灵活性和符合开闭原则等优点,但也会增加复杂性、扩展困难、违反单一职责原则以及不易扩展新品种等缺点。在使用时需要权衡各种因素,根据实际情况选择是否使用该模式。


Python 实现抽象工厂设计模式示例代码(一):

假设我们有一个汽车工厂,生产豪华车和普通车两种车型,每种车型又有不同的部件(引擎、轮胎等)。抽象工厂模式可以为这些不同车型的部件提供一个统一的接口。

from abc import ABC, abstractmethod

# 抽象产品 - 轮胎
class Tire(ABC):
    @abstractmethod
    def build(self):
        pass

# 具体产品 - 豪华车轮胎
class LuxuryTire(Tire):
    def build(self):
        print("Building luxury tire")

# 具体产品 - 普通车轮胎
class RegularTire(Tire):
    def build(self):
        print("Building regular tire")

# 抽象工厂
class CarFactory(ABC):
    @abstractmethod
    def create_tire(self) -> Tire:
        pass

# 具体工厂 - 生产豪华车
class LuxuryCarFactory(CarFactory):
    def create_tire(self) -> Tire:
        return LuxuryTire()

# 具体工厂 - 生产普通车
class RegularCarFactory(CarFactory):
    def create_tire(self) -> Tire:
        return RegularTire()

if __name__ == "__main__":
    # 客户端
    luxury_factory = LuxuryCarFactory()
    luxury_tire = luxury_factory.create_tire()
    luxury_tire.build()  # 输出:Building luxury tire

    regular_factory = RegularCarFactory()
    regular_tire = regular_factory.create_tire()
    regular_tire.build()  # 输出:Building regular tire

在这个示例中,CarFactory 是抽象工厂接口,包含一个创建轮胎的抽象方法。LuxuryCarFactoryRegularCarFactory 是具体工厂,分别实现了抽象工厂接口,用于生产豪华车和普通车的轮胎。LuxuryTireRegularTire 是具体产品,分别表示豪华车和普通车的轮胎。客户端可以通过具体工厂获取特定类型车辆的轮胎。


Python 实现抽象工厂设计模式示例代码(二):

假设我们有一个电子设备制造公司,需要生产手机和电脑两种产品,每种产品需要不同类型的屏幕和处理器。我们可以使用抽象工厂模式来管理这些产品的生产。

from abc import ABC, abstractmethod

# 抽象产品 - 屏幕
class Screen(ABC):
    @abstractmethod
    def build(self):
        pass

# 具体产品 - 手机屏幕
class PhoneScreen(Screen):
    def build(self):
        print("Building phone screen")

# 具体产品 - 电脑屏幕
class ComputerScreen(Screen):
    def build(self):
        print("Building computer screen")

# 抽象产品 - 处理器
class Processor(ABC):
    @abstractmethod
    def assemble(self):
        pass

# 具体产品 - 手机处理器
class PhoneProcessor(Processor):
    def assemble(self):
        print("Assembling phone processor")

# 具体产品 - 电脑处理器
class ComputerProcessor(Processor):
    def assemble(self):
        print("Assembling computer processor")

# 抽象工厂
class DeviceFactory(ABC):
    @abstractmethod
    def create_screen(self) -> Screen:
        pass

    @abstractmethod
    def create_processor(self) -> Processor:
        pass

# 具体工厂 - 生产手机
class PhoneFactory(DeviceFactory):
    def create_screen(self) -> Screen:
        return PhoneScreen()

    def create_processor(self) -> Processor:
        return PhoneProcessor()

# 具体工厂 - 生产电脑
class ComputerFactory(DeviceFactory):
    def create_screen(self) -> Screen:
        return ComputerScreen()

    def create_processor(self) -> Processor:
        return ComputerProcessor()

if __name__ == "__main__":
    # 客户端
    phone_factory = PhoneFactory()
    phone_screen = phone_factory.create_screen()
    phone_processor = phone_factory.create_processor()

    phone_screen.build()  # 输出:Building phone screen
    phone_processor.assemble()  # 输出:Assembling phone processor

    computer_factory = ComputerFactory()
    computer_screen = computer_factory.create_screen()
    computer_processor = computer_factory.create_processor()

    computer_screen.build()  # 输出:Building computer screen
    computer_processor.assemble()  # 输出:Assembling computer processor

这个示例模拟了一个设备制造公司,通过抽象工厂模式来管理手机和电脑的生产。DeviceFactory 是抽象工厂接口,定义了创建屏幕和处理器的抽象方法。PhoneFactoryComputerFactory 是具体工厂类,分别生产手机和电脑,并实现了对应的产品创建方法。PhoneScreenPhoneProcessorComputerScreenComputerProcessor 分别是具体产品类,用于表示手机和电脑的不同部件。客户端通过具体工厂获取特定类型设备的屏幕和处理器。


使用抽象工厂设计模式时,需要注意哪些地方?

在使用抽象工厂设计模式时,需要注意以下几点:

  1. 工厂方法数量: 确保抽象工厂中的方法数量不要过多,以免导致接口过于臃肿和复杂。应该根据实际情况进行适当的抽象和设计,避免过度设计。

  2. 产品族的变动: 如果需要添加新的产品族,抽象工厂和具体工厂都需要进行相应的调整和扩展,这可能导致修改工厂的代码。

  3. 产品等级结构的变动: 如果需要添加新的产品等级结构,比如新增一种类型的产品(如键盘、鼠标等),也需要修改工厂的代码来支持这些变化。

  4. 工厂选择逻辑: 客户端在使用抽象工厂模式时,可能需要选择合适的具体工厂。这个选择可能需要使用其他设计模式(如工厂方法、简单工厂等)来实现,需要谨慎设计。

  5. 对扩展的支持: 设计时应该考虑到系统的扩展性,使得新增产品或者新增产品族的支持变得容易,不会破坏原有代码结构。

  6. 合理的命名规范: 工厂、产品等命名应该清晰易懂,能够清晰表达其作用和职责,便于团队协作和维护。

  7. 充分的抽象性: 抽象工厂应该具有足够的抽象性,能够满足不同的业务需求,但又不要过度抽象,导致难以理解和应用。

  8. 单一职责原则: 每个具体工厂应该专注于创建特定类型的产品,符合单一职责原则,避免一个具体工厂负责太多不同类型产品的创建。

总的来说,使用抽象工厂模式时,需要考虑工厂方法数量、产品族和等级结构的变动、工厂选择逻辑、扩展性、命名规范、抽象性和单一职责原则等因素,合理设计和组织工厂结构,确保系统易于扩展和维护。


本文就到这里了,感谢您的阅读 。别忘了点赞、收藏~ Thanks♪(・ω・)ノ 🍇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/173110.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

广州华锐互动:3D模拟体验火箭发射过程有什么教育意义?

3D虚拟还原火箭发射过程在教育领域有着深远的意义。它能够为学生提供直观、生动的体验,帮助他们更好地理解和掌握相关知识,激发他们对科技的兴趣和探索欲望。 首先,3D虚拟还原火箭发射过程可以帮助学生更好地理解和掌握航天科技知识。在火箭发…

【数据结构】栈和队列的模拟实现

前言:前面我们学习了单链表并且模拟了它的实现,今天我们来进一步学习,来学习栈和队列吧!一起加油各位,后面的路只会越来越难走需要我们一步一个脚印! 💖 博主CSDN主页:卫卫卫的个人主页 &#x…

Leetcode 第 372 场周赛题解

Leetcode 第 372 场周赛题解 Leetcode 第 372 场周赛题解题目1:2937. 使三个字符串相等思路代码复杂度分析 题目2:2938. 区分黑球与白球思路代码复杂度分析 题目3:2939. 最大异或乘积思路代码复杂度分析 题目4:2940. 找到 Alice 和…

演示命令执行漏洞无回现如何渗透

演示命令执行漏洞无回现如何渗透 在DNSlog 获取一个域名 使用dvwa中的命令执行来ping此域名 执行后在DNSlog收到解析,证明命令执行成功

VSCode任务tasks.json中的问题匹配器problemMatcher的问题匹配模式ProblemPattern详解

☞ ░ 前往老猿Python博客 ░ https://blog.csdn.net/LaoYuanPython 一、简介 在 VS Code 中,tasks.json 文件中的 problemMatcher 字段用于定义如何解析任务输出中的问题(错误、警告等)。 problemMatcher有三种配置方式,具体可…

欧科云链研究院:从香港SFC最新文件看链上交易合规必备之选

出品|欧科云链研究院 作者|Hedy Bi 近日,香港证监会在其官网发布“致持牌法团、获证监会发牌的虚拟资产服务提供者及有联系实体的通函 - 打击洗钱/恐怖分子资金筹集经更新的《打击洗钱/恐怖分子资金筹集的自我评估查…

图形学 -- Ray Tracing 光线追踪

参考视频:Lecture 13 Ray Tracing 1_哔哩哔哩_bilibili Ray tracing 原因 Rasterization 格栅话不能处理好global effects,如↓ 简介反射:光线在到达人眼前不止弹射一次 基本假设 1)光是沿着直线传播 2)光线交叉…

2023年山东省安全员B证证模拟考试题库及山东省安全员B证理论考试试题

题库来源:安全生产模拟考试一点通公众号小程序 2023年山东省安全员B证证模拟考试题库及山东省安全员B证理论考试试题是由安全生产模拟考试一点通提供,山东省安全员B证证模拟考试题库是根据山东省安全员B证最新版教材,山东省安全员B证大纲整理…

CMap数据库筛选化学药物

数据库clue.io 文献链接:连接图谱:使用基因表达特征连接小分子、基因和疾病 |科学 (science.org) 基本模式:利用CMap将差异基因列表与数据库参考数据集比对;根据差异表达基因在参考基因表达谱富集情况得到一个相关性分数&#…

YOLOv7训练:_pickle.UnpicklingError: STACK_GLOBAL requires str

在YOLOv7训练过程中,出现以下错误: 原因就是: 这个数据集在其他地方运行过产生了**.cache**文件 解决方案(亲测有效): 删除数据集中的所有 label.cache文件,比如训练集、验证集、测试集都删…

SpingBoot原理

目录 配置优先级Bean管理 (掌握)Bean的获取 ApplicationContext.getBeanBean的作用域 Scope("prototype") Lazy第三方Bean Bean Configuration SpringBoot底层原理 起步依赖与自动配置(无需手撸但面试高频知识点)自动配置引入第三方依赖常见方案方案1:Com…

hook io异常注入

文中code https://gitee.com/bbjg001/darcy_common/tree/master/io_hook 需求引入 最近工作需要,需要验证一下我们的服务在硬盘故障下的鲁棒性。 从同事大佬哪里了解到hook技术,可以通过LD_PRELOAD这个环境变量拦截依赖库的调用链,将对标准…

PowerShell无人参与安装最新版本SQL Server Management Studio (SSMS)

文章目录 下载SQL Server Management Studio (SSMS)Power Shell实现无人安装推荐阅读 下载SQL Server Management Studio (SSMS) SSMS 19.2 是最新的正式发布 (GA) 版本。 如果已经安装了 SSMS 19 预览版,需要在安装 SSMS 19.2 之前将其卸载。 如果安装了 SSMS 19.…

【Java】多线程-单例模式/volatile-指令重排序

单例模式即代码中只有一个实例的模式 适用场景:有些场景下,有的类只能有一个对象,不能有多个 要注意:在单例模式下,要保证不能产生多个实例 1、饿汉模式 class Singleton{private static Singleton instance new …

人员定位系统人员聚集风险监测预警功能为企业安全生产保驾护航!

危化企业生产区域由于装置设施开停工、设备检维修或其它原因,会导致在局部作业区域出现作业操作人员、指挥管理人员不定时、不定点的聚集情况,一旦发生泄漏中毒、火灾爆炸、高温高热物质喷溅等事故,人员聚集将会在一定程度上加重事故后果的严…

【Echart】Echart设置label太长隐藏:

文章目录 第一种:竖排显示第二种:显示部分第三种:强制显示所有标签并旋转 第一种:竖排显示 xAxis: {type: category,data: res.data.data.sz.xAxis,axisLabel:{fontSize:12,formatter: function(value) {return value.split().joi…

nginx基础组件的使用

文章目录 一、Nginx 的相关组件介绍1.1、ngx_palloc相关源码1.2、ngx_array组件的相关源码1.3、ngx_array的数据结构1.4、ngx_cycle简介和相关源码1.5、ngx_list相关源码1.6、ngx_list 的数据结构 二、Nginx 组件的使用2.1、makefile的编写2.2、ngx_pallocngx_array的使用2.3、…

【代码随想录】刷题笔记Day33

前言 Day33虽说是一个月,但是从第一篇开始实际上已经过了8个月了,得抓紧啊 46. 全排列 - 力扣(LeetCode) 前面组合就强调过差别了,这道题是排序,因此每次要从头到尾扫,结合used数组 class So…