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

设计模式——工厂方法模式

文章目录

      • 工厂方法模式简介
      • 工厂方法模式的组成部分
      • 工厂方法模式的结构
      • Factory和Method的含义
      • 工厂方法模式的应用场景
      • 工厂方法模式的示例
        • 1. 文档生成器
        • 2. 数据库连接

工厂方法模式简介

工厂方法模式(Factory Method Pattern)是一种创建型设计模式,它定义了一个用于创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让一个类的实例化延迟到其子类。

工厂方法模式的组成部分

  1. 产品(Product):定义工厂方法所创建对象的接口。
  2. 具体产品(ConcreteProduct):实现产品接口的具体类。
  3. 创建者(Creator):声明工厂方法,该方法返回一个产品类型的对象。创建者的子类通常会提供这个工厂方法的实现。
  4. 具体创建者(ConcreteCreator):实现工厂方法,返回具体产品实例。

工厂方法模式的结构

from abc import ABC, abstractmethod# 产品接口
class Product(ABC):@abstractmethoddef use(self):pass# 具体产品
class ConcreteProductA(Product):def use(self):return "Using Product A"class ConcreteProductB(Product):def use(self):return "Using Product B"# 创建者
class Creator(ABC):@abstractmethoddef factory_method(self) -> Product:passdef some_operation(self) -> str:product = self.factory_method()result = f"Creator: The same creator's code has just worked with {product.use()}"return result# 具体创建者
class ConcreteCreatorA(Creator):def factory_method(self) -> Product:return ConcreteProductA()class ConcreteCreatorB(Creator):def factory_method(self) -> Product:return ConcreteProductB()# 使用工厂方法
def client_code(creator: Creator) -> None:print(f"Client: I'm not aware of the creator's class, but it still works.\n{creator.some_operation()}")print("App: Launched with ConcreteCreatorA.")
client_code(ConcreteCreatorA())print("\nApp: Launched with ConcreteCreatorB.")
client_code(ConcreteCreatorB())

Factory和Method的含义

  • Factory(工厂):在工厂方法模式中,"工厂"指的是负责创建对象的角色。具体来说,工厂是一个方法,它提供对象的创建逻辑。这个方法由抽象创建者声明,具体创建者实现。

  • Method(方法):工厂方法是一个方法(函数),这个方法的职责是创建并返回一个产品对象的实例。工厂方法模式中的"方法"强调的是通过这个方法来进行对象的创建,而不是直接调用构造函数。

工厂方法模式的应用场景

  1. 需要生成不同类型的对象:当系统需要生成不同类型或不同配置的对象时,可以使用工厂方法模式来实现对象的创建。
  2. 客户端不需要知道所创建对象的具体类:客户端通过工厂方法来获取对象的实例,而不需要知道具体的实现类。
  3. 系统的产品类较为复杂且易变:当产品类的创建逻辑复杂或容易发生变化时,工厂方法模式可以将创建逻辑封装在子类中,使得主类代码简洁且稳定。

工厂方法模式的示例

1. 文档生成器

假设我们有一个文档生成系统,可以生成不同格式的文档,例如 PDF 和 Word 文档。我们可以使用工厂方法模式来创建具体的文档生成器。

from abc import ABC, abstractmethodclass Document(ABC):@abstractmethoddef save(self):passclass PDFDocument(Document):def save(self):return "Saving as PDF"class WordDocument(Document):def save(self):return "Saving as Word"class DocumentCreator(ABC):@abstractmethoddef create_document(self) -> Document:passclass PDFCreator(DocumentCreator):def create_document(self) -> Document:return PDFDocument()class WordCreator(DocumentCreator):def create_document(self) -> Document:return WordDocument()def client_code(creator: DocumentCreator):document = creator.create_document()print(document.save())print("Client: Creating a PDF document.")
client_code(PDFCreator())print("\nClient: Creating a Word document.")
client_code(WordCreator())
2. 数据库连接

假设我们有一个应用程序,可以连接到不同类型的数据库,例如 MySQL 和 PostgreSQL。我们可以使用工厂方法模式来创建具体的数据库连接器。

from abc import ABC, abstractmethodclass DatabaseConnection(ABC):@abstractmethoddef connect(self):passclass MySQLConnection(DatabaseConnection):def connect(self):return "Connecting to MySQL"class PostgreSQLConnection(DatabaseConnection):def connect(self):return "Connecting to PostgreSQL"class DatabaseCreator(ABC):@abstractmethoddef create_connection(self) -> DatabaseConnection:passclass MySQLCreator(DatabaseCreator):def create_connection(self) -> DatabaseConnection:return MySQLConnection()class PostgreSQLCreator(DatabaseCreator):def create_connection(self) -> DatabaseConnection:return PostgreSQLConnection()def client_code(creator: DatabaseCreator):connection = creator.create_connection()print(connection.connect())print("Client: Connecting to MySQL database.")
client_code(MySQLCreator())print("\nClient: Connecting to PostgreSQL database.")
client_code(PostgreSQLCreator())

通过使用工厂方法模式,我们将对象的创建过程与使用过程分离,使得代码更加灵活和可扩展。不同的具体创建者类实现不同的创建逻辑,使得系统可以方便地扩展和维护。

http://www.lryc.cn/news/380524.html

相关文章:

  • apksigner jarsigner.md
  • 在SQL中使用explode函数展开数组的详细指南
  • JavaScript 预编译与执行机制解析
  • 多路h265监控录放开发-(12)完成全部开始录制和全部停止录制代码
  • Redis源码学习:Redis对象和5种数据类型的工作原理
  • 从理论到实践掌握UML
  • LabVIEW Windows与RT系统的比较与选择
  • docker搭建mongo副本集
  • 关于Pytorch转换为MindSpore的一点建议
  • JetBrains IDEA 新旧UI切换
  • iOS KeychainAccess的了解与使用
  • STM32 Customer BootLoader 刷新项目 (二) 方案介绍
  • 2-14 基于matlab的GA优化算法优化车间调度问题
  • Program-of-Thoughts(PoT):结合Python工具和CoT提升大语言模型数学推理能力
  • ansible setup模块
  • 【2024最新华为OD-C/D卷试题汇总】[支持在线评测] LYA的测试用例执行计划(100分) - 三语言AC题解(Python/Java/Cpp)
  • NSIS 入门教程 (一)
  • cve-2015-3306-proftpd-vulfocus
  • 超详细!想进华为od的请疯狂看我!
  • MQTT协议与TCP/IP协议在性能上的区别
  • LeetCode 每日一题 2024/6/17-2024/6/23
  • FlinkCDC pipeline模式 mysql-to-paimon.yaml
  • mysql数据库入门手册
  • 增强大型语言模型(LLM)可访问性:深入探究在单块AMD GPU上通过QLoRA微调Llama 2的过程
  • 空间复杂度 线性表,顺序表尾插。
  • linux创建用户、切换用户、删除用户
  • BC64 牛牛的快递(c++)
  • 离线linux通过USB连接并使用手机网络
  • I2C总线8位IO扩展器PCF8574
  • webClient + fastJSON2 获取json格式的数据,同时解析至java class 并 下划线转驼峰