一、工厂方法模式核心概念
工厂方法模式(Factory Method Pattern)是一种创建型设计模式,属于经典23种设计模式之一。其核心思想是:定义一个创建对象的接口,但将具体对象的实例化过程延迟到子类中实现。这种模式通过引入抽象层,将对象的创建与使用解耦,使系统更具扩展性。
关键角色解析
抽象产品(Product)
定义产品的公共接口,所有具体产品必须实现这些方法。例如:from abc import ABC, abstractmethod class Animal(ABC): @abstractmethod def speak(self): pass
具体产品(ConcreteProduct)
实现抽象产品接口的具体类,如Dog
和Cat
:class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!"
抽象工厂(Creator)
声明工厂方法,返回抽象产品类型:class AnimalFactory(ABC): @abstractmethod def create_animal(self): pass
具体工厂(ConcreteCreator)
实现抽象工厂的接口,负责创建具体产品实例:class DogFactory(AnimalFactory): def create_animal(self): return Dog() class CatFactory(AnimalFactory): def create_animal(self): return Cat()
二、工厂方法模式vs简单工厂模式
特性 | 工厂方法模式 | 简单工厂模式 |
---|---|---|
核心思想 | 通过子类延迟实例化到具体工厂 | 集中创建逻辑到单个工厂类 |
扩展性 | 符合开闭原则,新增产品只需添加子类 | 添加新产品需修改工厂类 |
复杂度 | 类数量较多,系统复杂度较高 | 结构简单,适合产品较少场景 |
适用场景 | 产品族扩展频繁,需动态选择工厂 | 产品类型固定,创建逻辑简单 |
三、Python实现工厂方法模式的三种方式
方式1:类方法工厂
利用@classmethod
实现工厂方法,避免实例化工厂类:
class Animal:
@classmethod
def factory(cls, animal_type):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError("Invalid animal type")
# 使用示例
animal = Animal.factory("dog")
print(animal.speak()) # 输出:Woof!
方式2:抽象基类强制实现
通过abc
模块强制子类实现工厂方法:
from abc import ABC, abstractmethod
class AnimalFactory(ABC):
@abstractmethod
def create(self):
pass
class DogFactory(AnimalFactory):
def create(self):
return Dog()
# 客户端代码
factory = DogFactory()
animal = factory.create()
方式3:动态工厂映射
结合字典实现灵活映射关系:
class AnimalFactory:
_factories = {
"dog": Dog,
"cat": Cat
}
@classmethod
def create(cls, animal_type):
return cls._factories[animal_type]()
# 使用示例
animal = AnimalFactory.create("cat")
四、工厂方法模式优缺点分析
✅ 优点
解耦创建与使用
客户端无需知道具体类名,只需通过工厂接口获取对象。符合开闭原则
新增产品时,只需添加具体工厂和产品类,无需修改现有代码。支持多态性
不同工厂可返回同一接口的不同实现,便于替换实现逻辑。
❌ 缺点
类数量膨胀
每新增一个产品需对应一个工厂类,增加系统复杂度。抽象层引入
过度使用可能导致代码可读性下降,需权衡设计复杂度。
五、实际应用场景
框架开发
Django框架中的表单和模型字段创建:from django import forms class CustomForm(forms.Form): name = forms.CharField() # 工厂方法动态生成字段 def field_factory(field_type): if field_type == "text": return forms.CharField() elif field_type == "email": return forms.EmailField()
插件系统
为不同插件提供统一创建接口:class Plugin: @abstractmethod def load(self): pass class ImagePlugin(Plugin): def load(self): print("Loading image plugin") class VideoPlugin(Plugin): def load(self): print("Loading video plugin") class PluginFactory: @staticmethod def create(plugin_type): if plugin_type == "image": return ImagePlugin() elif plugin_type == "video": return VideoPlugin()
日志系统
根据配置动态创建日志处理器:class Logger: @abstractmethod def log(self, message): pass class FileLogger(Logger): def log(self, message): with open("log.txt", "a") as f: f.write(message) class ConsoleLogger(Logger): def log(self, message): print(message) class LoggerFactory: @staticmethod def get_logger(logger_type): if logger_type == "file": return FileLogger() else: return ConsoleLogger()
六、总结
工厂方法模式通过抽象工厂和具体工厂的分离,为对象创建提供了灵活的扩展机制。在Python中,可结合@classmethod
、抽象基类(abc
模块)或字典映射等方式实现。其核心价值在于将对象创建逻辑封装到独立模块,降低系统耦合度,特别适用于产品类型可能动态扩展的场景。
实践建议:当系统需要频繁添加新产品,且客户端不关心具体实现时,优先使用工厂方法模式;若产品类型固定且数量较少,可考虑简单工厂模式以降低复杂度。