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

轻松创建对象——简单工厂模式(Python实现)

1. 引言

大家好,又见面了!今天我们要聊的是设计模式中的“万能钥匙”——简单工厂模式。想象一下,如果每次你都得亲自动手创建各种对象,不仅累得像个陀螺,还可能搞得一团糟。别怕,简单工厂模式来拯救你!它就像一个神奇的工厂,可以根据你的需求生产出各种对象。今天,我们就来揭开这个神奇模式的面纱,让你轻松创建对象不再烦恼。准备好了吗?Let’s go!

2. 什么是简单工厂模式

简单工厂模式(Simple Factory Pattern)是一种创建型设计模式,它定义一个工厂类,根据传入的参数决定创建哪一种产品类的实例。简单来说,简单工厂模式就是把创建对象的任务交给一个专门的工厂类,让工厂来决定生产哪种对象,咱们只需安心享用即可。

3. 简单工厂模式的实现

示例一:形状工厂

假如你是个艺术家,需要画各种形状,圆形、方形啥的,你可以用简单工厂模式让工厂帮你搞定这些形状对象:

代码实现
class Shape:def draw(self):passclass Circle(Shape):def draw(self):print("Drawing a Circle")class Square(Shape):def draw(self):print("Drawing a Square")class ShapeFactory:@staticmethoddef create_shape(shape_type):if shape_type == "circle":return Circle()elif shape_type == "square":return Square()else:return None# 使用示例
factory = ShapeFactory()
shape1 = factory.create_shape("circle")
shape1.draw()  # 输出: Drawing a Circleshape2 = factory.create_shape("square")
shape2.draw()  # 输出: Drawing a Square
详细代码解析
  • Shape是个接口类,定义了draw方法,咱们所有的形状都要实现它;
  • CircleSquare类分别实现了Shape接口,具体画啥样子它们说了算;
  • ShapeFactory类有个静态方法create_shape,根据传入的形状类型参数创建并返回对应的形状对象;
  • 我们只需通过调用ShapeFactory.create_shape方法并传入形状类型,就能轻松得到相应的形状对象。
示例二:日志记录器工厂

现在你是个开发者,搞个日志系统,你想要不同级别的日志记录器来帮你分门别类记录信息,简单工厂模式也能派上用场:

代码实现
class Logger:def log(self, message):passclass InfoLogger(Logger):def log(self, message):print(f"INFO: {message}")class ErrorLogger(Logger):def log(self, message):print(f"ERROR: {message}")class LoggerFactory:@staticmethoddef create_logger(logger_type):if logger_type == "info":return InfoLogger()elif logger_type == "error":return ErrorLogger()else:return None# 使用示例
logger_factory = LoggerFactory()
info_logger = logger_factory.create_logger("info")
info_logger.log("This is an informational message.")  # 输出: INFO: This is an informational message.error_logger = logger_factory.create_logger("error")
error_logger.log("This is an error message.")  # 输出: ERROR: This is an error message.
详细代码解析
  • Logger是个接口类,定义了log方法;
  • InfoLoggerErrorLogger类实现了Logger接口,分别负责记录不同级别的日志;
  • LoggerFactory类的静态方法create_logger根据传入的日志类型参数创建并返回对应的日志记录器对象;
  • 你只需通过调用LoggerFactory.create_logger方法并传入日志类型参数,就能得到相应的日志记录器对象。
示例三:数据库连接工厂

假如你现在是个DBA,需要管理多个数据库连接,简单工厂模式同样能帮你搞定这个问题:

代码实现
class DatabaseConnection:def connect(self):passclass MySQLConnection(DatabaseConnection):def connect(self):print("Connecting to MySQL database...")class PostgreSQLConnection(DatabaseConnection):def connect(self):print("Connecting to PostgreSQL database...")class DatabaseConnectionFactory:@staticmethoddef create_connection(db_type):if db_type == "mysql":return MySQLConnection()elif db_type == "postgresql":return PostgreSQLConnection()else:return None# 使用示例
db_factory = DatabaseConnectionFactory()
mysql_connection = db_factory.create_connection("mysql")
mysql_connection.connect()  # 输出: Connecting to MySQL database...postgresql_connection = db_factory.create_connection("postgresql")
postgresql_connection.connect()  # 输出: Connecting to PostgreSQL database...
详细代码解析
  • DatabaseConnection是个接口类,定义了connect方法;
  • MySQLConnectionPostgreSQLConnection类实现了DatabaseConnection接口,分别负责不同数据库的连接;
  • DatabaseConnectionFactory类的静态方法create_connection根据传入的数据库类型参数创建并返回对应的数据库连接对象;
  • 你只需通过调用DatabaseConnectionFactory.create_connection方法并传入数据库类型参数,就能得到相应的数据库连接对象。

4. 简单工厂模式的优缺点

优点
  • 解耦:把对象的创建过程封装在工厂类里,客户端代码只需关心怎么用,不用关心怎么创建;
  • 灵活性:通过工厂类可以灵活地创建不同类型的对象,扩展性杠杠的。
缺点
  • 违背开闭原则:每次新增对象类型,都得改工厂类,比较麻烦;
  • 单一职责问题:工厂类负责创建所有对象,复杂项目里可能会比较臃肿。

6.示意图

图片来源:https://xie.infoq.cn/article/270b6bbfd752d9906bf0a09df

img

7. 总结

简单工厂模式就是这么神奇,它让对象的创建变得简单又高效,适用于各种需要灵活创建对象的场景。虽然它有一些缺点,但在大多数情况下,简单工厂模式依然是个非常实用的设计模式。
希望今天的分享能让大家对简单工厂模式有更深入的理解。如果你在项目中也用到了简单工厂模式,欢迎留言分享你的经验和见解!
在这里插入图片描述

相关文章:

  • vue 中使用element-ui实现锚点定位表单
  • 矮油,希喂、喜崽、爱立方主食冻干是超贵的进口平替?最新测评
  • 大二暑假 + 大三上
  • uniapp小程序打开地图导航
  • 2024国内排名靠前的十大源码交易平台
  • 《Unity3D高级编程之进阶主程》第二章 架构(二) - 软件系统架构思维方式
  • keepalived HA nginx方案
  • vue3记个坑关于router的特点
  • Reflector简介-archlinux更新镜像列表工具
  • Kafka 进阶指南
  • vue3引入本地静态资源图片
  • 免费的CMS指纹识别系统
  • 【动态规划 前缀和】2478. 完美分割的方案数
  • 国产音频放大器工作原理以及应用领域
  • 外贸企业选择什么网络?
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • “寒冬”下的金三银四跳槽季来了,帮你客观分析一下局面
  • Android 架构优化~MVP 架构改造
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • java B2B2C 源码多租户电子商城系统-Kafka基本使用介绍
  • java8 Stream Pipelines 浅析
  • Linux Process Manage
  • React Native移动开发实战-3-实现页面间的数据传递
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Spring-boot 启动时碰到的错误
  • vue自定义指令实现v-tap插件
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 给新手的新浪微博 SDK 集成教程【一】
  • 前端面试之闭包
  • 区块链技术特点之去中心化特性
  • 我看到的前端
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • 终端用户监控:真实用户监控还是模拟监控?
  • 阿里云ACE认证之理解CDN技术
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​【C语言】长篇详解,字符系列篇3-----strstr,strtok,strerror字符串函数的使用【图文详解​】
  • ​Distil-Whisper:比Whisper快6倍,体积小50%的语音识别模型
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​渐进式Web应用PWA的未来
  • #if #elif #endif
  • (三)SvelteKit教程:layout 文件
  • (转)mysql使用Navicat 导出和导入数据库
  • .net core使用ef 6
  • .net 怎么循环得到数组里的值_关于js数组
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET连接数据库方式
  • /bin/rm: 参数列表过长"的解决办法
  • /etc/fstab和/etc/mtab的区别
  • @RequestBody的使用
  • @RequestMapping-占位符映射
  • [ 云计算 | AWS ] AI 编程助手新势力 Amazon CodeWhisperer:优势功能及实用技巧
  • [04] Android逐帧动画(一)
  • [2016.7 day.5] T2