工厂模式
问题
Python 中如何实现工厂模式?
答案
简单工厂
from abc import ABC, abstractmethod
class Serializer(ABC):
@abstractmethod
def serialize(self, data: dict) -> str: ...
class JSONSerializer(Serializer):
def serialize(self, data: dict) -> str:
import json
return json.dumps(data)
class XMLSerializer(Serializer):
def serialize(self, data: dict) -> str:
return f"<data>{data}</data>"
# 简单工厂函数
def create_serializer(format: str) -> Serializer:
serializers = {
"json": JSONSerializer,
"xml": XMLSerializer,
}
cls = serializers.get(format)
if not cls:
raise ValueError(f"Unknown format: {format}")
return cls()
s = create_serializer("json")
s.serialize({"name": "Alice"})
注册工厂(可扩展)
from typing import Callable
class SerializerFactory:
_registry: dict[str, Callable[[], Serializer]] = {}
@classmethod
def register(cls, format: str):
"""装饰器注册"""
def decorator(serializer_cls):
cls._registry[format] = serializer_cls
return serializer_cls
return decorator
@classmethod
def create(cls, format: str) -> Serializer:
creator = cls._registry.get(format)
if not creator:
raise ValueError(f"Unknown: {format}")
return creator()
@SerializerFactory.register("json")
class JSONSerializer(Serializer):
def serialize(self, data: dict) -> str:
import json
return json.dumps(data)
@SerializerFactory.register("yaml")
class YAMLSerializer(Serializer):
def serialize(self, data: dict) -> str:
import yaml
return yaml.dump(data)
# 使用
s = SerializerFactory.create("json")
Python 特色
Python 的一等函数和装饰器让工厂模式的实现比 Java 简洁得多。注册工厂模式特别常用——在 Flask/Django 的路由注册、CLI 子命令注册中都能看到。
常见面试问题
Q1: 简单工厂和注册工厂的区别?
答案:
- 简单工厂:工厂函数中硬编码所有产品类,新增产品需要修改工厂(违反开闭原则)
- 注册工厂:产品类自行注册到工厂,新增产品只需添加
@register装饰器
Q2: Python 中还有什么地方用到工厂模式?
答案:
dict.fromkeys()— 类方法工厂datetime.now()/datetime.fromtimestamp()— 替代构造器logging.getLogger(name)— 工厂 + 注册表- SQLAlchemy
create_engine()— 根据 URL 创建不同驱动