当前位置: 首页 > news >正文

Python设计模式 - 抽象工厂模式

定义

抽象工厂模式是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

产品等级结构与产品族

为了更好地理解抽象工厂模式,先引入两个概念:

  1. 产品等级结构:就是产品的继承结构。例如电视机抽象类有A品牌电视机子类和B品牌电视机子类,那么抽象电视机和具体品牌的电视机就构成了一个产品等级结构。
  2. 产品族:同一个工厂生产的,位于不同产品等级结构中的一组产品。例如海尔工厂生产的海尔电视机、海尔电冰箱就构成了一个产品族。

结构

在这里插入图片描述

  • 抽象工厂(Abstract Factory):声明一组用于创建一个产品族产品的工厂方法,每个工厂方法对应一种产品。
  • 具体工厂(Concrete Factory):实现抽象工厂中的工厂方法,这些方法创建的产品构成了一个产品族,每种产品都位于不同的产品等级结构中。
  • 抽象产品(Abstract Product):定义产品对象的接口。
  • 具体产品(Concrete Product):实现产品接口的具体产品对象。

应用场景

  1. 跨平台的产品系列:当需要为不同的平台(如Windows、Mac、Linux)创建一系列相关的产品时,可以使用抽象工厂模式。每个具体工厂类实现工厂方法来创建一个平台的所有产品。例如,跨平台的GUI框架需要针对不同操作系统生成不同风格的按钮、文本框等组件。
  2. 使用多个产品族:系统中有多于一个的产品族,而每次只使用其中某一个产品族,客户端可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族。例如,窗口中的按钮、文本框可以根据用户的选择按照不同的风格来展示。

优缺点

优点:

  1. 封装对象创建:抽象工厂模式将一系列相关对象的创建封装在一起,客户端无需关心对象的创建过程和具体类型。这减少了代码的耦合度,使系统更易于维护和扩展。
  2. 产品族的一致性:使用一个具体工厂创建的产品对象可以确保属于同一个产品族,且它们之间是兼容的。这避免了客户端在组合不同产品时可能出现的不兼容问题。
  3. 易于扩展:当需要引入新的产品族时,只需添加新的具体工厂类和对应的具体产品类,而不需要修改现有代码。这样能够确保系统的开放-封闭原则,即对扩展开放,对修改封闭。

缺点:

  1. 难以支持新产品类型:如果要添加新的产品等级结构,需要修改抽象工厂类及所有的具体工厂类,这违反了开放-封闭原则,增加维护成本。因此在使用抽象方法模式之前要进行全面考虑,尽量不要在设计完成后增加或删除产品等级结构。

代码示例

from abc import ABC, abstractmethod# 抽象产品 - 按钮
class Button(ABC):@abstractmethoddef click(self):pass# 抽象产品 - 文本框
class TextBox(ABC):@abstractmethoddef input(self, text):pass# 具体产品 - Windows 按钮
class WindowsButton(Button):def click(self):print("Windows Button Clicked")# 具体产品 - Windows 文本框
class WindowsTextBox(TextBox):def input(self, text):print(f"Windows TextBox input: {text}")# 具体产品 - Mac 按钮
class MacButton(Button):def click(self):print("Mac Button Clicked")# 具体产品 - Mac 文本框
class MacTextBox(TextBox):def input(self, text):print(f"Mac TextBox input: {text}")# 抽象工厂
class GUIFactory(ABC):@abstractmethoddef create_button(self):pass@abstractmethoddef create_textbox(self):pass# 具体工厂 - Windows 工厂
class WindowsFactory(GUIFactory):def create_button(self):return WindowsButton()def create_textbox(self):return WindowsTextBox()# 具体工厂 - Mac 工厂
class MacFactory(GUIFactory):def create_button(self):return MacButton()def create_textbox(self):return MacTextBox()# 客户端代码
def client(factory: GUIFactory):button = factory.create_button()textbox = factory.create_textbox()button.click()textbox.input("Hello World")# 使用 Windows 工厂
print("Using Windows Factory:")
client(WindowsFactory())# 使用 Mac 工厂
print("\nUsing Mac Factory:")
client(MacFactory())

抽象工厂模式和工厂方法模式的比较

抽象工厂模式是工厂方法模式的进一步延伸,我们从以下几点进行比较它们:

  1. 系统开销:工厂方法模式中的每个工厂只生产一种产品,可能会导致系统中存在大量的工厂类,会增加系统的开销。而抽象工厂模式将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,极大地减少了工厂类的数量。
  2. 扩展性:工厂方法模式增加新产品比较容易,只需要增加对应产品类和工厂方法类即可。抽象工厂模式增加新的产品族比较容易,但增加新的产品类型,需要修改抽象工厂类及所有的具体工厂类,扩展性稍差。
  3. 适用场景:工厂方法模式适用于系统只需要一个产品的多种变体的场景,抽象方法模式适用于系统需要创建多个相关产品族的场景。

参考

《设计模式的艺术》

相关文章:

  • Java学习Day20
  • RabbitMQ、Kafka对比(超详细),Kafka、RabbitMQ、RocketMQ的区别
  • 接口自动化测试框架中动态参数接口,加密接口,签名接口你们是怎么处理的?
  • TCP如何建立长连接
  • Jar工具完全指南:从入门到精通
  • C语言学习——函数
  • MySQL常用的日期和时间函数
  • oracle 比较两个值取小使用LEAST函数
  • 2024年湖北省建筑施工特种作业人员证书延期申请/年审
  • 精彩回顾 | ROS暑期“无人机自主追踪小车”训练营
  • 深度学习四大框架之争(Tensorflow、Pytorch、Keras和Paddle)
  • 鸿蒙笔记--Socket
  • 数据结构(邓俊辉)学习笔记】词典 02—— 散列函数
  • 用python实现求两个整数的最大公约数
  • vue 开发工具 Hbuilder 简介及应用
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Apache Zeppelin在Apache Trafodion上的可视化
  • C学习-枚举(九)
  • JavaScript中的对象个人分享
  • js 实现textarea输入字数提示
  • Lucene解析 - 基本概念
  • Python十分钟制作属于你自己的个性logo
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • 简析gRPC client 连接管理
  • 开源SQL-on-Hadoop系统一览
  • 聊聊sentinel的DegradeSlot
  • 强力优化Rancher k8s中国区的使用体验
  • 树莓派 - 使用须知
  • 一个SAP顾问在美国的这些年
  • 移动端 h5开发相关内容总结(三)
  • 再谈express与koa的对比
  • HanLP分词命名实体提取详解
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • #微信小程序:微信小程序常见的配置传值
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (03)光刻——半导体电路的绘制
  • (175)FPGA门控时钟技术
  • (2024,RWKV-5/6,RNN,矩阵值注意力状态,数据依赖线性插值,LoRA,多语言分词器)Eagle 和 Finch
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (三十五)大数据实战——Superset可视化平台搭建
  • (提供数据集下载)基于大语言模型LangChain与ChatGLM3-6B本地知识库调优:数据集优化、参数调整、Prompt提示词优化实战
  • **python多态
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .Net 6.0--通用帮助类--FileHelper
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .net(C#)中String.Format如何使用
  • .NET6 开发一个检查某些状态持续多长时间的类
  • .NET企业级应用架构设计系列之应用服务器
  • .NET未来路在何方?