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

Python设计模式 - 简单工厂模式

定义

简单工厂模式是一种创建型设计模式,它通过一个工厂类来创建对象,而不是通过客户端直接实例化对象。

结构

在这里插入图片描述
工厂类(Factory):负责创建对象的实例。工厂类通常包含一个方法,根据输入参数的不同创建并返回不同的对象
产品类(Product):工厂类创建的对象接口或抽象类,所有具体产品类需要实现或继承这个接口或抽象类。
具体产品类(ConcreteProduct):实现了产品接口的具体类。

应用场景

  1. 多种产品对象的创建:当系统需要创建多种类型的对象(不宜过多),而且这些对象有着相似的结构或接口时,可以使用简单工厂模式来集中管理对象的创建逻辑。这有助于提高代码的可维护性和扩展性。例如,不同类型的图形对象、不同类型的报表生成器等。
  2. 避免直接实例化复杂对象:当对象的创建过程较为复杂,涉及多种初始化步骤时,可以使用简单工厂模式,将这些初始化步骤封装在工厂类中,简化客户端代码。例如,不同类型的数据库连接、复杂的对象初始化流程等。

优缺点

优点:

  1. 简化客户端代码:客户端代码不需要了解具体产品类的创建细节,只需调用工厂类的创建方法即可获得所需的对象。这减少了客户端代码的复杂性,使其更容易维护和理解。
  2. 集中管理对象的创建:对象的创建逻辑集中在工厂类中,便于统一管理和控制。这有助于在一个地方进行修改和调整,从而避免在多个地方重复修改代码,提高了代码的可维护性。
  3. 便于扩展:当需要增加新产品类时,只需在工厂类中添加相应的创建逻辑,客户端代码无需修改。这使得系统在一定程度上具有较好的扩展性。

缺点:

  1. 违背开闭原则:每当需要添加新的产品类型时,都必须修改工厂类以添加新的创建逻辑。这违反了开闭原则,增加了维护成本。
  2. 违背单一职责原则:工厂类不仅负责创建对象,还承担了对象的选择逻辑,可能会导致工厂类变得复杂,难以维护。
  3. 不可避免的条件判断:工厂类中通常会包含大量的条件判断语句(如if-else或switch-case),用于确定需要创建哪种类型的对象。这些条件判断语句会随着产品种类的增加而变得冗长且复杂。

代码示例

from abc import ABC, abstractmethodclass Shape(ABC):@abstractmethoddef draw(self):passclass Circle(Shape):def draw(self):return "Drawing a Circle"class Rectangle(Shape):def draw(self):return "Drawing a Rectangle"class ShapeFactory:@staticmethoddef create_shape(shape_type):if shape_type == "CIRCLE":return Circle()elif shape_type == "RECTANGLE":return Rectangle()else:raise ValueError("Unknown shape type")if __name__ == "__main__":# 使用工厂类创建对象shape = ShapeFactory.create_shape("CIRCLE")print(shape.draw())  # 输出: Drawing a Circleshape = ShapeFactory.create_shape("RECTANGLE")print(shape.draw())  # 输出: Drawing a Rectangle

参考

《设计模式的艺术》

相关文章:

  • Linux驱动开发笔记(十一)tty子系统及其驱动
  • AMSR/ADEOS-II L1A Raw Observation Counts V003地球表面和大气微波辐射的详细观测数据
  • 计算机组成原理笔记-第1章 计算机系统概论
  • 大疆无人机航点飞行KMZ文件提取航点坐标
  • 保存和调取得分的简易方法
  • Github 2024-06-19 C开源项目日报 Top9
  • C#面: 能够将非静态的方法覆写成静态方法吗?
  • Jenkins macos 下 failed to create dmg 操作不被允许hdiutil: create failed - 操作不被允许?
  • 使用Redis优化Java应用的性能
  • 如何将 ChatGPT 集成到你的应用中
  • lua中的lfs库介绍
  • vm.max_map_count是什么?起到什么作用
  • 剖析 Kafka 消息丢失的原因
  • MySQL中的客户端选项(三)
  • 【一步一步了解Java系列】:认识异常类
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • egg(89)--egg之redis的发布和订阅
  • emacs初体验
  • extract-text-webpack-plugin用法
  • JSONP原理
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • Netty+SpringBoot+FastDFS+Html5实现聊天App(六)
  • rabbitmq延迟消息示例
  • VUE es6技巧写法(持续更新中~~~)
  • 仿天猫超市收藏抛物线动画工具库
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 微信开源mars源码分析1—上层samples分析
  • 我感觉这是史上最牛的防sql注入方法类
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • ​LeetCode解法汇总2182. 构造限制重复的字符串
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • # 消息中间件 RocketMQ 高级功能和源码分析(七)
  • $.proxy和$.extend
  • (12)Hive调优——count distinct去重优化
  • (C语言)球球大作战
  • (k8s)kubernetes集群基于Containerd部署
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (转)VC++中ondraw在什么时候调用的
  • (转)重识new
  • *算法训练(leetcode)第四十五天 | 101. 孤岛的总面积、102. 沉没孤岛、103. 水流问题、104. 建造最大岛屿
  • .Net 8.0 新的变化
  • .NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)
  • .NET/C#⾯试题汇总系列:集合、异常、泛型、LINQ、委托、EF!(完整版)
  • .net6 当连接用户的shell断掉后,dotnet会自动关闭,达不到长期运行的效果。.NET 进程守护
  • .NET开源项目介绍及资源推荐:数据持久层
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [ 物联网 ]拟合模型解决传感器数据获取中数据与实际值的误差的补偿方法
  • [16/N]论得趣
  • [2669]2-2 Time类的定义