Python 中的工厂模式(Factory Patterns)
工厂模式是一类创建型设计模式,主要解决对象创建的问题,让对象的创建与使用分离,提高代码的灵活性和可扩展性。
在 GoF 的 23 种设计模式中,与“工厂”相关的有两种:
- 工厂方法模式(Factory Method)
- 抽象工厂模式(Abstract Factory)
此外,还有一种常见的简化版:简单工厂(Simple Factory)(严格来说不属于 GoF 23 种,但非常实用)。
下面用 Python 详细讲解这三种工厂模式。
1. 简单工厂(Simple Factory)
最简单的一种,不属于 GoF 标准模式,但实际项目中使用最多。
场景:根据输入类型创建不同类的实例。
class Dog:
def speak(self):
return "Woof!"
class Cat:
def speak(self):
return "Meow!"
class AnimalFactory:
@staticmethod
def create_animal(animal_type: str):
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
else:
raise ValueError(f"Unknown animal type: {animal_type}")
# 使用
animal = AnimalFactory.create_animal("dog")
print(animal.speak()) # Woof!
优点:调用者无需知道具体类名
缺点:每次新增动物类型都需要修改工厂类,违反开闭原则
2. 工厂方法模式(Factory Method)
定义一个创建对象的接口,让子类决定实例化哪个类。
核心思想:一个工厂类对应一种产品,新增产品时新增对应的工厂子类。
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) -> Animal:
pass
# 具体工厂
class DogFactory(AnimalFactory):
def create_animal(self) -> Animal:
return Dog()
class CatFactory(AnimalFactory):
def create_animal(self) -> Animal:
return Cat()
# 使用(客户端代码)
def client_code(factory: AnimalFactory):
animal = factory.create_animal()
print(animal.speak())
client_code(DogFactory()) # Woof!
client_code(CatFactory()) # Meow!
优点:
- 符合开闭原则:新增动物只需新增类和工厂类,无需修改现有代码
- 解耦:客户端只依赖抽象工厂
适用场景:知道要创建哪一组相关对象,但想延迟到子类决定具体类
3. 抽象工厂模式(Abstract Factory)
提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
场景:需要创建产品族(如不同风格的 UI 组件:Windows 风格 vs Mac 风格)
from abc import ABC, abstractmethod
# 抽象产品
class Button(ABC):
@abstractmethod
def render(self):
pass
class Checkbox(ABC):
@abstractmethod
def check(self):
pass
# 具体产品 - Windows 风格
class WinButton(Button):
def render(self):
return "Render Windows button"
class WinCheckbox(Checkbox):
def check(self):
return "Check Windows checkbox"
# 具体产品 - Mac 风格
class MacButton(Button):
def render(self):
return "Render Mac button"
class MacCheckbox(Checkbox):
def check(self):
return "Check Mac checkbox"
# 抽象工厂
class GUIFactory(ABC):
@abstractmethod
def create_button(self) -> Button:
pass
@abstractmethod
def create_checkbox(self) -> Checkbox:
pass
# 具体工厂
class WinFactory(GUIFactory):
def create_button(self):
return WinButton()
def create_checkbox(self):
return WinCheckbox()
class MacFactory(GUIFactory):
def create_button(self):
return MacButton()
def create_checkbox(self):
return MacCheckbox()
# 客户端代码
def client_code(factory: GUIFactory):
button = factory.create_button()
checkbox = factory.create_checkbox()
print(button.render())
print(checkbox.check())
# 根据操作系统选择工厂
import platform
if platform.system() == "Windows":
factory = WinFactory()
else:
factory = MacFactory()
client_code(factory)
优点:保证创建的产品是兼容的(同一族)
缺点:新增产品(如添加 Slider)需要修改所有工厂,扩展性差
三种工厂模式对比
| 模式 | 复杂度 | 扩展性(加新产品) | 扩展性(加新产品族) | 典型场景 |
|---|---|---|---|---|
| 简单工厂 | 低 | 差(修改工厂) | 好 | 类型不多、变化不频繁 |
| 工厂方法 | 中 | 好 | 差 | 每种产品独立,经常扩展新类型 |
| 抽象工厂 | 高 | 差(修改所有工厂) | 好 | 需要产品族(如主题、风格) |
Python 中的实用建议
- Python 是动态语言,很多时候可以用函数或字典映射代替简单工厂:
animals = {"dog": Dog, "cat": Cat}
animal = animals[animal_type]()
- 对于配置驱动的项目(如插件系统),工厂方法 + 注册机制很常见:
class AnimalRegistry:
factories = {}
@classmethod
def register(cls, name, factory):
cls.factories[name] = factory
@classmethod
def create(cls, name):
return cls.factories[name]().create_animal()
AnimalRegistry.register("dog", DogFactory)
animal = AnimalRegistry.create("dog")
如果你想看更实际的例子(如数据库连接工厂、配置文件解析工厂),或者某个模式的变体,请告诉我!