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

设计模式Python版 工厂方法模式

文章目录

  • 前言
  • 一、工厂方法模式
  • 二、工厂方法模式示例
  • 三、工厂方法模式客户端改进
  • 四、工厂方法模式隐藏工厂方法(可选)


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、工厂方法模式

工厂方法模式(Factory Method Pattern)

  • 定义:工厂方法模式提供一个抽象工厂接口来声明抽象工厂方法,而由其子类来具体实现工厂方法,创建具体的产品对象。客户端针对抽象工厂编程,可在运行时再指定具体工厂类。

  • 解决问题:如何通过不同的工厂来创建不同类型的对象?(每个具体工厂只生产一个具体产品)

  • 使用场景:

    • 与简单工厂模式相比,新增产品时只需要增加新的具体产品和具体工厂类,不需要修改已有代码,符合开闭原则
    • 创建对象的过程需要根据上下文环境变化,或者一个类不知道它所创建的对象的类
    • 一个类希望由其子类来指定创建的对象,或者系统需要通过子类来扩展
  • 具体场景:

    • 日志记录器:根据不同的日志级别(如DEBUG、INFO、ERROR)来创建不同的日志记录器。

    • 数据库访问:根据不同的数据库类型(如MySQL、Oracle、SQLite)来创建不同的数据库访问对象。

    • 支付网关:根据不同的支付方式(如信用卡、PayPal、支付宝)来创建不同的支付处理器。

    • 文件解析器:根据不同的文件类型(如PDF、Word、Excel)来创建不同的文件解析器。

    • UI组件:在图形用户界面应用程序中,根据不同的操作系统(如Windows、Mac、Linux)来创建不同的UI组件。

  • 组成:

    • 抽象产品(Product):定义产品的接口
    • 具体产品(Concrete Product):实现了抽象产品接口的具体类。
    • 抽象工厂(Creator):声明工厂方法,该方法返回一个产品类型的对象
    • 具体工厂(Concrete Creator):定义工厂方法以返回一个具体产品类的实例。
  • 优点:

    • 良好的扩展性。
    • 工厂方法模式是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。
  • 缺点:

    • 系统中类的个数成对增加,在一定程度上增加了系统的复杂度

在这里插入图片描述

二、工厂方法模式示例

使用工厂方法模式来设计日志记录器

# 模块 loggers.py
class Logger:"""抽象产品"""def write_log(self, msg: str):raise NotImplementedErrorclass FileLogger(Logger):"""具体产品"""def write_log(self, msg):print(f"文件日志记录:{msg}")class DatabaseLogger(Logger):def write_log(self, msg):print(f"数据库日志记录:{msg}")class LoggerFactory:"""抽象工厂"""def create_logger(self) -> Logger:raise NotImplementedErrorclass FileLoggerFactory(LoggerFactory):"""具体工厂"""def create_logger(self):# 创建文件等操作(略)return FileLogger()class DatabaseLoggerFactory(LoggerFactory):def create_logger(self):# 连接数据库等操作(略)return DatabaseLogger()# 客户端代码
factory = FileLoggerFactory()
logger = factory.create_logger()
logger.write_log('[22/Jan/2025 11:24:49] "GET /admin/ HTTP/1.1" 302 0')

三、工厂方法模式客户端改进

反射与配置文件:通过读取配置文件获取类名字符串,再使用反射机制,根据类名字符串生成对象。

  • 配置文件config.json
{"class_name": "DatabaseLoggerFactory"
}
  • 工具类文件utils.py
from pathlib import Path
import jsonclass JsonUtil:@staticmethoddef get_class_name():"""读取配置文件,返回配置文件中的配置"""path = Path("config.json")contents = path.read_text(encoding="utf-8")conf = json.loads(contents)return conf.get("class_name", None)
  • 客户端文件cli.py
import loggers
from utils import JsonUtilclass_name = JsonUtil.get_class_name()
klass = getattr(loggers, class_name)
factory: loggers.LoggerFactory = klass()
logger = factory.create_logger()
logger.write_log('[22/Jan/2025 11:24:49] "GET /admin/ HTTP/1.1" 302 0')### 输出结果
数据库日志记录:[22/Jan/2025 11:24:49] "GET /admin/ HTTP/1.1" 302 0

四、工厂方法模式隐藏工厂方法(可选)

通过将业务方法的调用移入工厂类,可以直接使用工厂对象来调用产品对象的业务方法,客户端无须直接使用工厂方法

class LoggerFactory:"""抽象工厂"""def write_log(self, msg: str):raise NotImplementedErrorclass FileLoggerFactory(LoggerFactory):"""具体工厂"""def __init__(self):self.logger = FileLogger()def write_log(self, msg):self.logger.write_log(msg)# 客户端代码
factory = FileLoggerFactory()
factory.write_log('[22/Jan/2025 11:24:49] "GET /admin/ HTTP/1.1" 302 0')

您正在阅读的是《设计模式Python版》专栏!关注不迷路~

相关文章:

设计模式Python版 工厂方法模式

文章目录 前言一、工厂方法模式二、工厂方法模式示例三、工厂方法模式客户端改进四、工厂方法模式隐藏工厂方法(可选) 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方…...

贝叶斯优化相关

贝叶斯优化相关 python中有很多模块支持贝叶斯优化,如bayesian-optimization、hyperopt,比较好用的是hyperopt,下面是对hyperopt文章的翻译,原文地址如下 https://districtdatalabs.silvrback.com/parameter-tuning-with-hyperop…...

【Matlab高端绘图SCI绘图全家桶更新版】在原60种绘图类型基础上更新

俗话说,一图胜千言。数据可视化便是将数据通过图形化的方式展现出来,它更加便于我们观察数据蕴含的的规律,洞察了数据蕴含的规律后,从而使我们能够做更好的进行科研表达和学术写作。 科研过程中,绘图是一项非常重要的…...

如何构建一个 GraphRAG 系统

构建一个 GraphRAG 系统以提升传统 RAG(检索增强生成)模型的性能,需要结合知识图谱和生成式语言模型的能力,以下是实现的关键步骤和方法: 1. 数据准备 (1) 收集数据 确保有足够的高质量文本数据源,如&…...

代码随想录算法训练营day34

代码随想录算法训练营 —day34 文章目录 代码随想录算法训练营前言一、62.不同路径动态规划动态规划空间优化 二、63. 不同路径 II动态规划动态规划优化空间版 三、343. 整数拆分动态规划贪心算法 96.不同的二叉搜索树总结 前言 今天是算法营的第34天,希望自己能够…...

单片机基础模块学习——按键

一、按键原理图 当把跳线帽J5放在右侧,属于独立按键模式(BTN模式),放在左侧为矩阵键盘模式(KBD模式) 整体结构是一端接地,一端接控制引脚 之前提到的都是使用了GPIO-准双向口的输出功能&#x…...

polars as pl

import polars as pl#和pandas类似,但是处理大型数据集有更好的性能. #necessary import pandas as pd#导入csv文件的库 import numpy as np#进行矩阵运算的库 #metric from sklearn.metrics import roc_auc_score#导入roc_auc曲线 #KFold是直接分成k折,StratifiedKFold还要考虑…...

重构(4)

(一)添加解释性变量,使得代码更容易理解,更容易调试,也可以方便功能复用 解释性的变量 总价格为商品总价(单价*数量)-折扣(超过100个以上的打9折)邮费(原价的…...

神经网络|(三)线性回归基础知识

【1】引言 前序学习进程中,已经对简单神经元的工作模式有所了解,这种二元分类的工作机制,进一步使用sigmoid()函数进行了平滑表达。相关学习链接为: 神经网络|(一)加权平均法,感知机和神经元-CSDN博客 神经网络|(二…...

deepseek R1 高效使用学习

直接提问 1、可以看到思考过程&#xff0c;可以当个学习工具 2、高效简介代码prompt <context> You are an expert programming AI assistant who prioritizes minimalist, efficient code. You plan before coding, write idiomatic solutions, seek clarification …...

STM32_SD卡的SDIO通信_基础读写

本篇将使用CubeMXKeil, 创建一个SD卡读写的工程。 目录 一、SD卡要点速读 二、SDIO要点速读 三、SD卡座接线原理图 四、CubeMX新建工程 五、CubeMX 生成 SD卡的SDIO通信部分 六、Keil 编辑工程代码 七、实验效果 实现效果&#xff0c;如下图&#xff1a; 一、SD卡 速读…...

【Docker】私有Docker仓库的搭建

一、准备工作 确保您的系统已安装Docker。如果没有安装&#xff0c;请参考Docker官方文档进行安装。 准备一个用于存储仓库数据的目录&#xff0c;例如/registry_data/。 二、拉取官方registry镜像 首先&#xff0c;我们需要从Docker Hub拉取官方的registry镜像。执行以下命…...

linux 管道符、重定向与环境变量

1. 输入输出重定向 在linux工作必须掌握的命令一文中&#xff0c;我们已经掌握了几乎所有基础常用的Linux命令&#xff0c;那么接下来的任务就是把多个命令适当的组合到一起&#xff0c;使其协同工作&#xff0c;会更高效的处理数据&#xff0c;做到这一点就必须搞清楚命令的输…...

Ansible fetch模块详解:轻松从远程主机抓取文件

在自动化运维的过程中&#xff0c;我们经常需要从远程主机下载文件到本地&#xff0c;以便进行分析或备份。Ansible的fetch模块正是为了满足这一需求而设计的&#xff0c;它可以帮助我们轻松地从远程主机获取文件&#xff0c;并将其保存到本地指定的位置。在这篇文章中&#xf…...

wireshark工具简介

目录 1 wireshark介绍 2 wireshark抓包流程 2.1 选择网卡 2.2 停止抓包 2.3 保存数据 3 wireshark过滤器设置 3.1 显示过滤器的设置 3.2 抓包过滤器 4 wireshark的封包列表与封包详情 4.1 封包列表 4.2 封包详情 参考文献 1 wireshark介绍 wireshark是非常流行的网络…...

51单片机——按键控制LED流水灯

引言 在电子制作和嵌入式系统学习中&#xff0c;51 单片机是一个经典且入门级的选择。按键控制 LED 流水灯是 51 单片机的一个基础应用&#xff0c;通过这个实例&#xff0c;我们可以深入了解单片机的输入输出控制原理。 51 单片机简介 51 单片机是对所有兼容 Intel 8051 指…...

【opencv】第9章 直方图与匹配

第9章 直方图与匹配 9.1 图像直方图概述 直方图广泛运用于很多计算机视觉运用当中&#xff0c;通过标记帧与帧之间显著的边 缘和颜色的统计变化&#xff0c;来检测视频中场景的变化。在每个兴趣点设置一个有相近 特征的直方图所构成“标签”,用以确定图像中的兴趣点。边缘、色…...

HTML5 Web Worker 的使用与实践

引言 在现代 Web 开发中&#xff0c;用户体验是至关重要的。如果页面在执行复杂计算或处理大量数据时变得卡顿或无响应&#xff0c;用户很可能会流失。HTML5 引入了 Web Worker&#xff0c;它允许我们在后台运行 JavaScript 代码&#xff0c;从而避免阻塞主线程&#xff0c;保…...

MVCC底层原理实现

MVCC的实现原理 了解实现原理之前&#xff0c;先理解下面几个组件的内容 1、 当前读和快照读 先普及一下什么是当前读和快照读。 当前读&#xff1a;读取数据的最新版本&#xff0c;并对数据进行加锁。 例如&#xff1a;insert、update、delete、select for update、 sele…...

基于ESP32-IDF驱动GPIO输出控制LED

基于ESP32-IDF驱动GPIO输出控制LED 文章目录 基于ESP32-IDF驱动GPIO输出控制LED一、点亮LED3.1 LED电路3.2 配置GPIO函数gpio_config()原型和头文件3.3 设置GPIO引脚电平状态函数gpio_set_level()原型和头文件3.4 代码实现并编译烧录 一、点亮LED 3.1 LED电路 可以看到&#x…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下&#xff0c;商品详情API作为连接电商平台与开发者、商家及用户的关键纽带&#xff0c;其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息&#xff08;如名称、价格、库存等&#xff09;的获取与展示&#xff0c;已难以满足市场对个性化、智能…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面

代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口&#xff08;适配服务端返回 Token&#xff09; export const login async (code, avatar) > {const res await http…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...