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

设计模式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 NotImplementedError


class 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 NotImplementedError


class 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 json

class JsonUtil:
    @staticmethod
    def 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 JsonUtil

class_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 NotImplementedError


class 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版》专栏!关注不迷路~


http://www.kler.cn/a/519228.html

相关文章:

  • 第 25 场 蓝桥月赛
  • 【Salesforce】审批流程,代理登录 tips
  • 【PyTorch】3.张量类型转换
  • openlava/LSF 用户组管理脚本
  • K8S中的数据存储之基本存储
  • FlinkSql使用中rank/dense_rank函数报错空指针
  • 【C语言】字符函数与字符串函数
  • 探寻 UTF - 8 和 GBK 的编码 “黑匣子”
  • 关注搜索引擎蜘蛛压力
  • vim 中粘贴内容时提示: -- (insert) VISUAL --
  • 【YOLOv11改进- 主干网络】YOLOv11+MobileNetV2(2018): 相比于 MobileNetV1 而言准确率更高,模型更小;
  • 【Linux】列出所有连接的 WiFi 网络的密码
  • 《Kotlin核心编程》下篇
  • 安装环境pytorch
  • centos7 配置国内镜像源安装 docker
  • 【分布式日志篇】从工具选型到实战部署:全面解析日志采集与管理路径
  • 使用 Pipeline 提高 Redis 批量操作性能
  • Java 反射机制:春招面试中的关键知识点
  • 【模型】RNN模型详解
  • w178智能学习平台系统设计与实现
  • 景联文科技加入AIIA联盟数据标注分委会
  • Linux的常用指令的用法
  • java定时任务备份数据库
  • php-phar打包避坑指南2025
  • 电梯系统的UML文档10
  • Redis-缓存