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

设计模式-工厂模式

概念:

工厂模式属于创建型设计模式,核心思想是将对象的创建过程封装到工厂类中,客户端无需关心具体对象的创建细节,实现创建与使用的解耦。

模式分类

  1. 简单工厂模式(静态工厂)

  2. 工厂方法模式(多态工厂)

  3. 抽象工厂模式(产品族工厂)

工厂模式的核心优势

1. 解耦创建与使用

  • 客户端代码无需依赖具体类,只需要与抽象接口交互
  • 符合依赖倒置原则(DIP)

2. 可扩展性强

  • 新增产品时,只需添加新的具体工厂和产品类
  • 符合开闭原则(对扩展开放,对修改关闭)

3. 统一创建逻辑

  • 将复杂的对象初始化过程封装在工厂中
  • 避免代码重复(例如:参数验证、资源分配)

简单工厂模式,抽象公共接口,然后封装不同类型,最后创建一个工厂(类比名)统一处理这些封装对象,然后在实现的时候根据传递的参数实例化不同的对象。

# 步骤1:定义产品接口
class Car:def drive(self):pass# 步骤2:创建具体产品
class Tesla(Car):def drive(self):print("特斯拉电动车启动...")class BMW(Car):def drive(self):print("宝马燃油车启动...")# 步骤3:创建工厂
class CarFactory:@staticmethoddef create_car(brand):if brand == "tesla":return Tesla()elif brand == "bmw":return BMW()else:raise ValueError("不支持的车型")# 使用示例
if __name__ == "__main__":# 通过工厂创建对象car1 = CarFactory.create_car("tesla")car2 = CarFactory.create_car("bmw")car1.drive()  # 输出:特斯拉电动车启动...car2.drive()  # 输出:宝马燃油车启动...

代码结构解析:

  1. Car 是产品基类(接口)
  2. TeslaBMW 是具体产品
  3. CarFactory 是工厂类,根据参数创建不同产品
  4. 使用者只需要和工厂交互,不需要知道具体类的创建细节

工厂模式的核心优势:将对象的创建和使用解耦,当需要新增产品时,只需要扩展工厂类,不需要修改已有代码。


下面以工厂方法模式为例进行完整实现,把产品和工厂都进行抽象,在最后调用的时候不需要实例化最上层的接口:


Python 代码实现

1. 定义抽象产品接口

from abc import ABC, abstractmethod# 抽象产品:车辆接口
class Vehicle(ABC):@abstractmethoddef start_engine(self):pass@abstractmethoddef stop_engine(self):pass

2. 实现具体产品类

# 具体产品:电动车
class ElectricCar(Vehicle):def start_engine(self):print("⚡️ 电动车电机启动(无声)")def stop_engine(self):print("⚡️ 电动车电机关闭")# 具体产品:燃油车
class GasolineCar(Vehicle):def start_engine(self):print("🔥 燃油车发动机启动(轰鸣声)")def stop_engine(self):print("🔥 燃油车发动机关闭")

3. 定义抽象工厂接口

# 抽象工厂
class VehicleFactory(ABC):@abstractmethoddef create_vehicle(self) -> Vehicle:pass

4. 实现具体工厂类

# 具体工厂:电动车工厂
class ElectricCarFactory(VehicleFactory):def create_vehicle(self) -> Vehicle:print("制造电动车:安装电池组、电机...")return ElectricCar()# 具体工厂:燃油车工厂
class GasolineCarFactory(VehicleFactory):def create_vehicle(self) -> Vehicle:print("制造燃油车:安装发动机、油箱...")return GasolineCar()

5. 客户端使用示例

def client_code(factory: VehicleFactory):# 客户端无需知道具体产品类型vehicle = factory.create_vehicle()vehicle.start_engine()vehicle.stop_engine()print("-" * 40)if __name__ == "__main__":# 选择电动车工厂electric_factory = ElectricCarFactory()client_code(electric_factory)# 选择燃油车工厂gasoline_factory = GasolineCarFactory()client_code(gasoline_factory)

输出结果

制造电动车:安装电池组、电机...
⚡️ 电动车电机启动(无声)
⚡️ 电动车电机关闭
----------------------------------------
制造燃油车:安装发动机、油箱...
🔥 燃油车发动机启动(轰鸣声)
🔥 燃油车发动机关闭
----------------------------------------

适用场景

  1. 需要创建多种类型对象,且这些对象有共同接口
  2. 创建过程涉及复杂初始化逻辑
  3. 需要根据运行时条件动态选择创建哪种对象
  4. 希望隐藏具体类的实现细节(例如SDK开发)

工厂方法 vs 简单工厂

特性工厂方法简单工厂
扩展性新增产品只需加新工厂类需要修改工厂类代码
符合开闭原则
复杂度较高(需要维护更多类)较低
适用场景大型项目、产品类型多小型项目、产品类型少

场景1:需要创建多种类型对象,且这些对象有共同接口

实际案例:跨平台文件存储服务
假设你需要支持将文件存储到不同云服务(阿里云OSS、腾讯云COS、AWS S3),但它们的上传/下载接口不同。

from abc import ABC, abstractmethod# 公共接口
class CloudStorage(ABC):@abstractmethoddef upload_file(self, local_path: str, remote_path: str):pass@abstractmethoddef download_file(self, remote_path: str, local_path: str):pass# 具体产品:阿里云OSS
class AliyunOSS(CloudStorage):def upload_file(self, local_path: str, remote_path: str):print(f"[阿里云] 上传 {local_path}{remote_path}")def download_file(self, remote_path: str, local_path: str):print(f"[阿里云] 下载 {remote_path}{local_path}")# 具体产品:腾讯云COS
class TencentCOS(CloudStorage):def upload_file(self, local_path: str, remote_path: str):print(f"[腾讯云] 上传 {local_path}{remote_path}")def download_file(self, remote_path: str, local_path: str):print(f"[腾讯云] 下载 {remote_path}{local_path}")# 工厂根据配置选择实现
class CloudStorageFactory:@staticmethoddef create_storage(provider: str) -> CloudStorage:if provider == "aliyun":return AliyunOSS()elif provider == "tencent":return TencentCOS()else:raise ValueError("不支持的云服务商")# 客户端代码无需知道具体实现
storage = CloudStorageFactory.create_storage("aliyun")
storage.upload_file("data.txt", "backup/data.txt")

场景2:创建过程涉及复杂初始化逻辑

实际案例:构建数据库连接对象
数据库连接需要处理参数校验、连接池初始化、超时设置等复杂步骤。

class DatabaseConnection:def __init__(self, host: str, port: int, user: str, password: str):# 复杂的初始化过程self._validate_config(host, port)self._init_connection_pool()self._set_timeout(30)print(f"已连接到 {host}:{port}")def _validate_config(self, host, port):if not host:raise ValueError("Invalid host")# 更多校验逻辑...def _init_connection_pool(self):print("初始化连接池...")def _set_timeout(self, seconds):print(f"设置超时时间:{seconds}秒")class DatabaseFactory:@staticmethoddef create_connection(config: dict) -> DatabaseConnection:# 封装所有复杂逻辑return DatabaseConnection(host=config["host"],port=config["port"],user=config["user"],password=config["password"])# 使用示例
config = {"host": "127.0.0.1","port": 3306,"user": "admin","password": "secret"
}
db = DatabaseFactory.create_connection(config)

场景3:运行时动态选择创建哪种对象

实际案例:根据操作系统创建不同风格的UI组件
在跨平台应用中,需要根据当前操作系统动态创建对应风格的按钮。

import platform# 抽象产品:按钮
class Button(ABC):@abstractmethoddef render(self):pass# 具体产品:Windows风格按钮
class WindowsButton(Button):def render(self):print("渲染一个Windows风格的按钮")# 具体产品:Mac风格按钮
class MacButton(Button):def render(self):print("渲染一个Mac风格的按钮")class UIFactory:@staticmethoddef create_button() -> Button:# 根据运行时系统类型决定os_name = platform.system()if os_name == "Windows":return WindowsButton()elif os_name == "Darwin":  # macOSreturn MacButton()else:raise NotImplementedError("不支持的操作系统")# 客户端代码
button = UIFactory.create_button()
button.render()  # 输出取决于当前操作系统

场景4:隐藏具体实现细节(SDK开发)

实际案例:支付SDK封装
作为SDK提供方,你希望隐藏支付宝/微信支付的具体实现,只暴露统一接口。

# SDK对外暴露的接口
class PaymentProcessor(ABC):@abstractmethoddef pay(self, amount: float):pass# 具体实现1(SDK内部实现)
class AlipayProcessor(PaymentProcessor):def pay(self, amount: float):print(f"调用支付宝接口支付 {amount} 元")# 具体实现2(SDK内部实现)
class WechatPayProcessor(PaymentProcessor):def pay(self, amount: float):print(f"调用微信支付接口支付 {amount} 元")class PaymentFactory:@staticmethoddef create_processor(payment_type: str) -> PaymentProcessor:if payment_type == "alipay":return AlipayProcessor()elif payment_type == "wechat":return WechatPayProcessor()else:raise ValueError("不支持的支付方式")# 开发者使用SDK时
processor = PaymentFactory.create_processor("alipay")
processor.pay(100.0)  # 开发者无需知道支付宝的具体实现

总结:工厂模式的核心价值

场景解决的问题实际效果
多种类型对象 + 共同接口统一不同实现的访问方式客户端代码无需关心具体类型
复杂初始化逻辑封装创建细节避免代码重复简化调用方代码,集中管理创建逻辑
运行时动态选择避免在业务代码中写大量if-else提升代码可维护性
隐藏实现细节(如SDK)降低使用方与实现的耦合度方便后续替换实现而不影响调用方

通过工厂模式,你可以将 变化的创建逻辑稳定的业务逻辑 分离,这正是面向对象设计原则中「封装变化」的经典体现。

http://www.xdnf.cn/news/307531.html

相关文章:

  • langchain使用推理模型如DeepSeek,删除回答中的推理过程<think></think>
  • 【安全】端口保护技术--端口敲门和单包授权
  • GaussDB数据库事务管理:高可靠与高性能的实践之道
  • 【C/C++】构造函数与析构函数
  • 某公园楼栋自由曲面薄壳结构自动化监测
  • 图形化编程重塑 IoT 边缘开发:技术革新与生态竞合新范式
  • 高等数学第五章---定积分(§5.3定积分的计算方法)
  • 柯西不等式应用题
  • K8S - ConfigMap 与 Secret - 应用配置与敏感信息管理
  • R8周:RNN实现阿尔茨海默病诊断
  • jmeter 执行顺序和组件作用域
  • Blender插件机制设计与Python实现
  • Qt学习Day0:Qt简介
  • [人机交互]协作与通信的设计
  • 数据管理平台是什么?企业应如何做好数据化管理?
  • 巧记英语四级单词 Unit7-下【晓艳老师版】
  • [java八股文][Java并发编程面试篇]并发安全
  • Android Service 从 1.0 到 16 的演进史
  • SQL报错注入成功特征
  • 人工智能100问☞第15问:人工智能的常见分类方式有哪些?
  • Unity Editor 扩展:查找缺失的 Image Sprite
  • 从入门到登峰-嵌入式Tracker定位算法全景之旅 Part 7 |TinyML 定位:深度模型在 MCU 上的部署
  • HarmonyOS开发:粒子动画使用详解
  • idea更换jdk版本操作
  • 分布式、高并发-Day03
  • 开源BI选型及DataEase搭建
  • 香港维尔利健康科技集团与亚洲医学研究院达成战略合作,联合打造智慧医疗应用技术实验室
  • ES6/ES11知识点 续五
  • 单调栈算法精解(Java实现):从原理到高频面试题
  • [250504] Moonshot AI 发布 Kimi-Audio:开源通用音频大模型,驱动多模态 AI 新浪潮