Python工厂模式
工厂模式是面向对象设计中最常用的创建型模式之一,它提供了一种创建对象的最佳方式。下面我将从基础到高级全面解析工厂模式在Python中的实现和应用。
工厂模式基础
1. 简单工厂模式(静态工厂)
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
class AnimalFactory:
@staticmethod
def create_animal(animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError(f"Unknown animal type: {animal_type}")
# 使用示例
dog = AnimalFactory.create_animal("dog")
print(dog.speak()) # 输出: Woof!
特点:
-
将对象创建逻辑集中管理
-
客户端不直接实例化具体类
-
违反开闭原则(新增类型需修改工厂)
2. 工厂方法模式
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
class AnimalFactory(ABC):
@abstractmethod
def create_animal(self):
pass
class DogFactory(AnimalFactory):
def create_animal(self):
return Dog()
class CatFactory(AnimalFactory):
def create_animal(self):
return Cat()
# 使用示例
dog_factory = DogFactory()
dog = dog_factory.create_animal()
print(dog.speak()) # 输出: Woof!
特点:
-
每个产品有对应的工厂类
-
符合开闭原则
-
客户端依赖抽象工厂而非具体类
高级工厂模式实现
1. 抽象工厂模式
class Button(ABC):
@abstractmethod
def render(self):
pass
class WindowsButton(Button):
def render(self):
return "Windows风格按钮"
class MacButton(Button):
def render(self):
return "Mac风格按钮"
class GUIFactory(ABC):
@abstractmethod
def create_button(self):
pass
class WindowsFactory(GUIFactory):
def create_button(self):
return WindowsButton()
class MacFactory(GUIFactory):
def create_button(self):
return MacButton()
# 使用示例
def create_ui(factory):
button = factory.create_button()
print(button.render())
create_ui(WindowsFactory()) # 输出: Windows风格按钮
create_ui(MacFactory()) # 输出: Mac风格按钮
2. 动态工厂注册
class AnimalFactory:
_animals = {}
@classmethod
def register(cls, animal_type, creator):
cls._animals[animal_type] = creator
@classmethod
def create(cls, animal_type):
creator = cls._animals.get(animal_type)
if not creator:
raise ValueError(f"Unknown animal type: {animal_type}")
return creator()
# 注册动物类型
AnimalFactory.register("dog", Dog)
AnimalFactory.register("cat", Cat)
# 使用示例
dog = AnimalFactory.create("dog")
print(dog.speak()) # 输出: Woof!
工厂模式实践
1. 使用类装饰器注册
class AnimalFactory:
_registry = {}
@classmethod
def register(cls, animal_type):
def wrapper(animal_class):
cls._registry[animal_type] = animal_class
return animal_class
return wrapper
@classmethod
def create(cls, animal_type):
animal_class = cls._registry.get(animal_type)
if not animal_class:
raise ValueError(f"Unknown animal type: {animal_type}")
return animal_class()
# 注册动物类
@AnimalFactory.register("dog")
class Dog:
def speak(self):
return "Woof!"
# 使用示例
dog = AnimalFactory.create("dog")
print(dog.speak()) # 输出: Woof!
2. 参数化工厂方法
class Vehicle:
def __init__(self, model):
self.model = model
class Car(Vehicle):
pass
class Truck(Vehicle):
pass
class VehicleFactory:
@classmethod
def create_vehicle(cls, vehicle_type, **kwargs):
if vehicle_type == "car":
return Car(**kwargs)
elif vehicle_type == "truck":
return Truck(**kwargs)
else:
raise ValueError(f"Unknown vehicle type: {vehicle_type}")
# 使用示例
car = VehicleFactory.create_vehicle("car", model="Tesla")
print(car.model) # 输出: Tesla
Python标准库中的应用
1. datetime
模块中的工厂方法
from datetime import datetime
# 使用类方法作为工厂
now = datetime.now() # 工厂方法创建当前时间对象
utc = datetime.utcnow() # 另一个工厂方法
print(f"Local: {now}, UTC: {utc}")
2. pathlib
中的路径工厂
from pathlib import Path
# Path是一个工厂类,根据操作系统返回不同子类
path = Path(".") # Windows返回WindowsPath,Unix返回PosixPath
print(type(path)) # 输出: <class 'pathlib.WindowsPath'>
工厂模式与依赖注入
class Database(ABC):
@abstractmethod
def query(self, sql):
pass
class MySQLDatabase(Database):
def query(self, sql):
return f"MySQL执行: {sql}"
class PostgreSQLDatabase(Database):
def query(self, sql):
return f"PostgreSQL执行: {sql}"
class DatabaseFactory:
@staticmethod
def create(db_type):
if db_type == "mysql":
return MySQLDatabase()
elif db_type == "postgresql":
return PostgreSQLDatabase()
else:
raise ValueError(f"未知数据库类型: {db_type}")
class Application:
def __init__(self, db_factory):
self.db = db_factory.create("mysql") # 配置决定具体类型
def run(self):
print(self.db.query("SELECT * FROM users"))
# 使用示例
app = Application(DatabaseFactory())
app.run() # 输出: MySQL执行: SELECT * FROM users
性能优化
1. 使用 __slots__
优化工厂产品类
class Product:
__slots__ = ['param1', 'param2'] # 固定属性列表
def __init__(self, p1, p2):
self.param1 = p1
self.param2 = p2
class ProductFactory:
@staticmethod
def create(p1, p2):
return Product(p1, p2)
2. 缓存常用对象
class ExpensiveObject:
def __init__(self, config):
self.config = config
# 模拟耗时初始化
import time
time.sleep(2)
class SmartFactory:
_cache = {}
@classmethod
def create(cls, config):
if config not in cls._cache:
cls._cache[config] = ExpensiveObject(config)
return cls._cache[config]
# 首次创建慢,后续快速返回缓存
obj1 = SmartFactory.create("A") # 耗时2秒
obj2 = SmartFactory.create("A") # 立即返回
设计原则
-
单一职责原则:创建逻辑与业务逻辑分离
-
开闭原则:通过扩展而非修改增加新产品
-
依赖倒置原则:依赖抽象而非具体实现
应用场景
-
对象创建逻辑复杂时
-
需要统一管理对象生命周期
-
系统需要支持多种配置或环境
-
需要隐藏具体实现类
工厂模式与其它模式对比
模式 | 特点 | 适用场景 |
---|---|---|
简单工厂 | 一个工厂创建所有产品 | 产品类型少且稳定 |
工厂方法 | 每个产品对应一个工厂 | 需要灵活扩展产品 |
抽象工厂 | 创建产品族 | 需要保证产品兼容性 |
建造者 | 分步构建复杂对象 | 对象构造过程复杂 |
完整示例:插件系统实现
class Plugin(ABC):
@abstractmethod
def execute(self):
pass
class PluginFactory:
_plugins = {}
@classmethod
def register(cls, plugin_name):
def wrapper(plugin_class):
cls._plugins[plugin_name] = plugin_class
return plugin_class
return wrapper
@classmethod
def create(cls, plugin_name, *args, **kwargs):
plugin_class = cls._plugins.get(plugin_name)
if not plugin_class:
raise ValueError(f"未知插件: {plugin_name}")
return plugin_class(*args, **kwargs)
# 注册插件
@PluginFactory.register("logger")
class LoggerPlugin(Plugin):
def execute(self):
print("日志记录插件执行")
@PluginFactory.register("analyzer")
class AnalyzerPlugin(Plugin):
def execute(self):
print("数据分析插件执行")
# 使用示例
plugins = ["logger", "analyzer"]
for name in plugins:
plugin = PluginFactory.create(name)
plugin.execute()
# 输出:
# 日志记录插件执行
# 数据分析插件执行
工厂模式是Python中实现灵活对象创建的强大工具,合理使用可以显著提高代码的可维护性和扩展性。根据具体需求选择适当的工厂模式变体,可以构建出更加优雅和健壮的系统架构。