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

Python设计模式-工厂模式

在这里插入图片描述

一、模式定义与核心思想

工厂模式(Factory Pattern)属于创建型设计模式,其核心思想是通过一个"工厂类"来创建对象,而不是直接调用类的构造函数。这种模式将对象的实例化过程封装起来,使系统在实例化对象时能获得更高的灵活性和可扩展性。

模式类型细分:

  1. 简单工厂模式(静态工厂)
  2. 工厂方法模式(多态工厂)
  3. 抽象工厂模式(产品族工厂)

二、模式实现与Python特性结合

2.1 简单工厂模式

class Button:def render(self): passclass WindowsButton(Button):def render(self):return "Windows风格按钮"class MacButton(Button):def render(self):return "Mac风格按钮"class ButtonFactory:@staticmethoddef create_button(os_type):if os_type == "windows":return WindowsButton()elif os_type == "mac":return MacButton()raise ValueError("未知操作系统类型")# 使用示例
button = ButtonFactory.create_button("windows")
print(button.render())  # 输出: Windows风格按钮

Python特性应用

  • 使用@staticmethod实现静态工厂方法
  • 利用鸭子类型(Duck Typing)实现多态

2.2 工厂方法模式(更符合开闭原则)

from abc import ABC, abstractmethodclass Button(ABC):@abstractmethoddef render(self): passclass WindowsButton(Button):def render(self):return "Windows风格按钮"class MacButton(Button):def render(self):return "Mac风格按钮"class Dialog(ABC):@abstractmethoddef create_button(self) -> Button: passdef render(self):button = self.create_button()return f"渲染 {button.render()}"class WindowsDialog(Dialog):def create_button(self) -> Button:return WindowsButton()class MacDialog(Dialog):def create_button(self) -> Button:return MacButton()# 客户端代码
def client_code(dialog: Dialog):print(dialog.render())client_code(WindowsDialog())  # 输出: 渲染 Windows风格按钮

Python特性亮点

  • 使用abc模块实现抽象基类
  • 类型注解(Type Hints)提高代码可读性
  • 符合依赖倒置原则(DIP)

2.3 抽象工厂模式(产品族创建)

class GUIFactory(ABC):@abstractmethoddef create_button(self): pass@abstractmethoddef create_checkbox(self): passclass WinFactory(GUIFactory):def create_button(self):return WindowsButton()def create_checkbox(self):return WindowsCheckbox()class MacFactory(GUIFactory):def create_button(self):return MacButton()def create_checkbox(self):return MacCheckbox()# 客户端代码
def create_ui(factory: GUIFactory):button = factory.create_button()checkbox = factory.create_checkbox()return button, checkbox

三、模式优势与适用场景

3.1 核心优势

  1. 解耦:将对象创建与使用分离
  2. 可扩展:新增产品类型时无需修改客户端代码
  3. 单一职责:创建逻辑集中管理
  4. 易于测试:可以轻松替换mock对象

3.2 典型应用场景

  • 系统需要支持多种类型的产品
  • 对象创建过程复杂或需要统一管理
  • 需要动态选择具体实现类
  • 框架需要提供扩展点(如Django的ModelAdmin)

四、Python特有实现技巧

4.1 使用类字典替代switch-case

class ButtonFactory:_buttons = {'windows': WindowsButton,'mac': MacButton,'linux': LinuxButton}@classmethoddef create_button(cls, os_type):button_class = cls._buttons.get(os_type.lower())if button_class:return button_class()raise ValueError(f"不支持的操作系统: {os_type}")

4.2 利用模块作为工厂

# buttons.py
def create_button(os_type):if os_type == "windows":return WindowsButton()# ...# 使用
from buttons import create_button

4.3 动态类注册机制

class PluginFactory:plugins = {}@classmethoddef register(cls, name):def wrapper(plugin_class):cls.plugins[name] = plugin_classreturn plugin_classreturn wrapper@classmethoddef create(cls, name, *args, **kwargs):return cls.plugins[name](*args, **kwargs)@PluginFactory.register('pdf')
class PDFExporter: pass

五、性能考量与最佳实践

  1. 缓存策略:对于创建成本高的对象,可以在工厂中实现缓存

    class DatabaseConnectionFactory:_instances = {}@classmethoddef get_connection(cls, config):key = frozenset(config.items())if key not in cls._instances:cls._instances[key] = RealDatabaseConnection(config)return cls._instances[key]
    
  2. 线程安全:在多线程环境下使用锁机制

    from threading import Lockclass ThreadSafeFactory:_lock = Lock()@classmethoddef create(cls):with cls._lock:# 创建实例return ExpensiveObject()
    
  3. 元类实现(高级技巧):

    class AutoRegister(type):def __new__(cls, name, bases, namespace):new_class = super().__new__(cls, name, bases, namespace)if not namespace.get('abstract', False):Factory.register(name.lower(), new_class)return new_class
    

六、与其他模式的关系

  1. vs 建造者模式:工厂关注产品类型,建造者关注构造过程
  2. vs 单例模式:工厂可以返回单例对象
  3. vs 策略模式:工厂创建对象,策略使用对象

七、实战案例:Django中的工厂模式

Django的模型表单就是工厂模式的典型应用:

from django.forms import modelform_factory# 动态创建表单类
ProductForm = modelform_factory(Product, fields='__all__',widgets={'name': TextInput(attrs={'class': 'special'})}
)

相关文章:

Python设计模式-工厂模式

一、模式定义与核心思想 工厂模式(Factory Pattern)属于创建型设计模式,其核心思想是通过一个"工厂类"来创建对象,而不是直接调用类的构造函数。这种模式将对象的实例化过程封装起来,使系统在实例化对象时能…...

SAP-ABAP:SAP的Open SQL和Native SQL详细对比

在SAP ABAP开发中,Open SQL和Native SQL是两种操作数据库的方式,它们的核心区别在于可移植性、功能范围及底层实现机制。以下是详细对比: 1. Open SQL:深入解析 1.1 核心特性 数据库抽象层 Open SQL 由 SAP 内核的 Database Interface (DBI) 转换为目标数据库的 SQL(如 …...

蓝桥杯 拼数(字符串大小比较)

题目描述 设有 n 个正整数 a1​…an​,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。 输入格式 第一行有一个整数,表示数字个数 n。 第二行有 n 个整数,表示给出的 n 个整数 ai​。 输出格式 一个正整…...

Server-Sent Events一种允许服务器向客户端发送实时更新的 Web API

Server-Sent Events(SSE)是一种允许服务器向客户端发送实时更新的 Web API。它基于 HTTP 协议,提供了一种单向的、服务器到客户端的通信机制,客户端可以通过监听服务器发送的事件来接收实时数据。下面从原理、使用场景、代码示例等…...

彻底解决VS2008编译错误:fatal error C1083 无法打开包括文件“stdint.h“

彻底解决VS2008编译错误:fatal error C1083 无法打开包括文件"stdint.h" 一、错误现象与本质原因 当在Visual Studio 2008中编译包含C99标准整数类型(如int8_t、uint32_t)的代码时,常出现以下编译错误: f…...

react从零开始的基础课

全文约5万字。 1.hello,.. // App.jsx import { useState } from react import reactLogo from ./assets/react.svg import viteLogo from /vite.svg import ./App.cssfunction App() {const [count, setCount] useState(0)return (<><Greeting name"world&qu…...

算法题型讲解

一.双指针 主要分为俩种类型&#xff1a; 1.左右指针&#xff1a;双指针指向开头&#xff0c;以一定标准移动或交换&#xff0c;对区域进行划分&#xff0c;或找到特殊点的位置 &#xff08;如&#xff1a;快慢指针判断有无环&#xff0c;移动零&#xff09; 2.对撞指针&am…...

操作主机的管理

1.在AD林范围内&#xff0c;有哪几个操作主机角色 架构主机&#xff08;Schema Master&#xff09; 功能&#xff1a;负责整个AD林中所有对象和属性的定义&#xff0c;是唯一可以更新目录架构的DC。架构更新会从架构主机复制到目录林中的所有其他域控制器。 作用范围&#xf…...

Redis和数据库一致性问题

操作模拟 1、先更新数据库还是先更新缓存&#xff1f; 1.1先更新缓存&#xff0c;再更新数据库 按并发的角度来说&#xff0c;有两个线程A、B&#xff0c;操作同一个数据&#xff0c;线程A先更新缓存为1&#xff0c;在线程A更新数据库之前&#xff0c;这时候线程B进来&#…...

第R8周:RNN实现阿尔茨海默病诊断(pytorch)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 本人往期文章可查阅&#xff1a; 深度学习总结 一、准备工作 &#x1f3e1; 我的环境&#xff1a; 语言环境&#xff1a;Python3.1…...

《穿透表象,洞察分布式软总线“无形”之奥秘》

分布式系统已成为众多领域的关键支撑技术&#xff0c;而分布式软总线作为实现设备高效互联的核心技术&#xff0c;正逐渐走入大众视野。它常被描述为一条“无形”的总线&#xff0c;这一独特属性不仅是理解其技术内涵的关键&#xff0c;更是把握其在未来智能世界中重要作用的切…...

C++基础精讲-02

文章目录 1.C/C申请、释放堆空间的方式对比1.1C语言申请、释放堆空间1.2C申请、释放堆空间1.2.1 new表达式申请数组空间 1.3回收空间时的注意事项1.4malloc/free 和 new/delete 的区别 2.引用2.1 引用的概念2.2 引用的本质2.3 引用与指针的联系与区别2.4 引用的使用场景2.4.1 引…...

【网络安全】Linux 命令大全

未经许可,不得转载。 文章目录 前言正文文件管理文档编辑文件传输磁盘管理磁盘维护网络通讯系统管理系统设置备份压缩设备管理其它命令前言 在网络安全工作中,熟练掌握 Linux 系统中的常用命令对于日常运维、日志分析和安全排查等任务至关重要。 以下是常用命令的整理汇总,…...

双相机结合halcon的条码检测

以下是针对提供的C#代码的详细注释和解释&#xff0c;结合Halcon库的功能和代码结构进行说明&#xff1a; --- ### **代码整体结构** 该代码是一个基于Halcon库的条码扫描类GeneralBarcodeScan&#xff0c;支持单台或双台相机的条码检测&#xff0c;并通过回调接口返回结果。…...

C++学习之ORACLE①

目录 1.ORACLE数据库简介 2..ORACLE数据库安装 3..ORACLE体系结构 4..ORACLE基本概念 5..ORACLE基本元素 6..ORACLE数据库启动和关闭 7.SQLPLUS登录ORACLE数据库相关操作 8.SQLPLUS的基本操作 9.oracle中上课使用的方案 10.SQL语言分类 11.SQL中的select语句语法和注…...

setInterval问题以及前端如何实现精确的倒计时

一、为什么setInterval不能实现 原因有两&#xff1a;1、js是单线程&#xff0c;基于事件循环执行其他任务&#xff08;这里建议读者可以多去了解一下浏览器线程与事件循环相关知识&#xff09; 2、setinterval是每隔delay时间&#xff0c;把逻辑放到任务队列中&#xff0c;而…...

企业级开发SpringBoost玩转Elasticsearch

案例 Spring Boot 提供了 spring-data-elasticsearch 模块&#xff0c;可以方便地集成 Elasticsearch。 下面我们将详细讲解如何在 Spring Boot 中使用 Elasticsearch 8&#xff0c;并提供示例代码。 1. 添加依赖: 首先&#xff0c;需要在 pom.xml 文件中添加 spring-data-e…...

从零开始的图论讲解(1)——图的概念,图的存储,图的遍历与图的拓扑排序

目录 前言 图的概念 1. 顶点和边 2. 图的分类 3. 图的基本性质 图的存储 邻接矩阵存图 邻接表存图 图的基本遍历 拓扑排序 拓扑排序是如何写的呢? 1. 统计每个节点的入度 2. 构建邻接表 3. 将所有入度为 0 的节点加入队列 4. 不断弹出队头节点&#xff0c;更新其…...

SpringBoot框架—启动原理

1.SpringBootApplication注解 在讲解启动原理之前先介绍一个非常重要的注解SpringBootApplication&#xff0c;这个注解在Springboot程序的入口文件Application.java中必须添加。SpringBootApplication是一个整合了三个核心注解的组合注解。 三个核心注解的作用机制&#xff1…...

Chapter 7: Compiling C++ Sources with CMake_《Modern CMake for C++》_Notes

Chapter 7: Compiling C Sources with CMake 1. Understanding the Compilation Process Key Points: Four-stage process: Preprocessing → Compilation → Assembly → LinkingCMake abstracts low-level commands but allows granular controlToolchain configuration (c…...

怎么检查网站CDN缓存是否生效

为什么要使用CDN缓存&#xff1f; 网站使用缓存可显著提升加载速度&#xff0c;减少服务器负载和带宽消耗&#xff0c;优化用户体验&#xff0c;增强架构稳定性&#xff0c;助力SEO优化&#xff0c;实现资源高效利用与性能平衡。 通过合理配置 CDN 缓存策略&#xff0c;可降低…...

【自然语言处理】深度学习中文本分类实现

文本分类是NLP中最基础也是应用最广泛的任务之一&#xff0c;从无用的邮件过滤到情感分析&#xff0c;从新闻分类到智能客服&#xff0c;都离不开高效准确的文本分类技术。本文将带您全面了解文本分类的技术演进&#xff0c;从传统机器学习到深度学习&#xff0c;手把手实现一套…...

vba讲excel转换为word

VBA将excel转换为word Sub ExportToWordFormatted() 声明变量Dim ws As Worksheet 用于存储当前活动的工作表Dim rng As Range 用于存储工作表的使用范围&#xff08;即所有有数据的单元格&#xff09;Dim rowCount As Long, colCount As Long 用于存储数据范围的行数和列数…...

ubuntu安装openWebUI和Dify【自用详细版】

系统版本&#xff1a;ubuntu24.04LTS 显卡&#xff1a;4090 48G 前期准备 先安装好docker和docker-compose&#xff0c;可以参考我之前文章安装&#xff1a; ubuntu安装docker和docker-compose【简单详细版】 安装openWebUI 先docker下载ollama docker pull ghcr.nju.edu.c…...

基于Flask的勒索病毒应急响应平台架构设计与实践

基于Flask的勒索病毒应急响应平台架构设计与实践 序言&#xff1a;安全工程师的防御视角 作为从业十年的网络安全工程师&#xff0c;我深刻理解勒索病毒防御的黄金时间法则——应急响应速度每提升1分钟&#xff0c;数据恢复成功率将提高17%。本文介绍的应急响应平台&#xff…...

Solidity基础入门—web3

Remix介绍 官网地址 Remix 是一个基于浏览器的 Solidity 开发环境&#xff0c;主要用于编写、测试、调试和部署以太坊智能合约。 Solidity基本数据类型 类型说明示例uint / int无符号 / 有符号整数uint256, int8, int256bool布尔类型&#xff08;true / false&#xff09;bo…...

spark数据清洗案例:流量统计

一、项目背景 在互联网时代&#xff0c;流量数据是反映用户行为和业务状况的重要指标。通过对流量数据进行准确统计和分析&#xff0c;企业可以了解用户的访问习惯、业务的热门程度等&#xff0c;从而为决策提供有力支持。然而&#xff0c;原始的流量数据往往存在格式不规范、…...

git commit时自动生成Change-ID

创建全局钩子目录&#xff1a; 创建一个全局的Git hooks目录&#xff1a; mkdir -p ~/.githooks 下载并设置commit-msg钩子脚本&#xff1a; 下载Gerrit的commit-msg钩子脚本&#xff0c;并放置在全局钩子目录中(如下载不了&#xff0c;可从本页面附件中下载&#xff0c;“…...

list的使用以及模拟实现

本章目标 1.list的使用 2.list的模拟实现 1.list的使用 在stl中list是一个链表,并且是一个双向带头循环链表,这种结构的链表是最优结构. 因为它的实现上也是一块线性空间,它的使用上是与string和vector类似的.但相对的因为底层物理结构上它并不像vector是线性连续的,它并没有…...

分布式防护节点秒级切换:实战配置与自动化运维

摘要&#xff1a;针对DDoS攻击导致节点瘫痪的问题&#xff0c;本文基于群联AI云防护的智能调度系统&#xff0c;详解如何实现节点健康检查、秒级切换与自动化容灾&#xff0c;并提供Ansible部署脚本。 一、分布式节点的核心价值 资源分散&#xff1a;攻击者难以同时击溃所有节…...