工厂方法模式和原型模式的总结非常准确、清晰,涵盖了定义、结构、核心思想与典型适用场景。下面是对两种模式的简要对比与补充说明,帮助加深理解:
✅ 共同点:
- 均属创建型设计模式,目标都是解耦对象的创建与使用;
- 都通过抽象(Product / Prototype 接口)隔离具体实现,提升可扩展性与可维护性。
✅ 关键区别:
| 维度 | 工厂方法模式 | 原型模式 |
|---|---|---|
| 创建依据 | 依赖子类“选择并构造”新实例 | 依赖已有实例“复制”生成新实例 |
| 是否需要类信息 | 需在编译/运行时知道具体类(如 ConcreteProduct) | 无需类名或构造逻辑,只需原型实例 |
| 初始化开销 | 每次调用工厂方法都执行完整构造过程 | 复制通常跳过复杂初始化(深/浅克隆需注意) |
| 灵活性 | 适合产品族固定、类型明确的场景 | 适合动态类型、配置驱动或对象状态易变的场景 |
💡 补充提示:
- 工厂方法常与抽象工厂模式组合使用,构建多层级产品族;
- 原型模式需谨慎处理深拷贝 vs 浅拷贝(尤其含引用类型成员时),Java 中需实现
Cloneable并重写clone(),Python 中可借助copy.deepcopy(); - 二者均可与注册表(Registry) 结合,实现基于字符串/标识符的动态创建(如
Factory.register("pdf", PdfDocument)或PrototypeManager.get("report_template").clone())。
# 示例:简易原型模式(Python)
import copy
class Prototype:
def clone(self):
return copy.deepcopy(self)
class Report(Prototype):
def __init__(self, title, data, author="Anonymous"):
self.title = title
self.data = data # 可能是大型列表或嵌套结构
self.author = author
# 使用
original = Report("Q3 Summary", [1, 2, 3, 4])
duplicate = original.clone() # 避免重复加载 data 的开销
duplicate.title = "Q3 Summary (Draft)"
这通常违背了开闭原则(Open/Closed Principle, OCP)。
✅ 开闭原则定义:
软件实体(类、模块、函数等)应该对扩展开放(open for extension),对修改关闭(closed for modification)。即:新增功能应通过添加新代码实现,而非修改已有稳定代码。
❌ 问题分析:
若 Creator 类(尤其是抽象基类或已发布的父类)既声明抽象工厂方法 factoryMethod(),又在自身内部硬编码实现了某个具体产品的创建逻辑(如直接 new ConcreteProductA()),则会出现以下违反 OCP 的情况:
- 修改封闭性被破坏:当需要支持新产品
ConcreteProductB时,开发者可能被迫修改Creator类的源码(例如增加if/else分支或switch),而不是仅新增一个ConcreteCreatorB子类; - 扩展开放性受限:本应通过继承(
ConcreteCreator)来扩展行为,却因父类“越俎代庖”承担了具体职责,导致子类无法自然接管或定制创建逻辑,削弱了多态扩展能力; - 违反单一职责与依赖倒置:
Creator同时承担“定义契约”和“提供默认实现”双重角色,且其默认实现直接依赖具体类(ConcreteProductA),违反了“依赖抽象,而非具体”的设计准则,也使测试与替换困难。
✅ 正确做法(符合 OCP):
Creator类只声明抽象工厂方法(如def factoryMethod(self) -> Product:),不提供任何具体产品实例化逻辑;- 或者,可提供一个空实现/抛出异常的默认方法(如
raise NotImplementedError),强制子类实现; - 若确需默认行为(如简单场景下的退化支持),应确保该默认实现仍基于抽象 Product 接口(例如返回一个轻量级默认实现类
DefaultProduct),且该类本身可被轻松替换——此时扩展仍只需新增ConcreteCreator,无需修改Creator。
📌 补充说明:
某些框架(如 Spring 的 AbstractFactoryBean)允许父类提供“可覆盖的默认实现”,但这属于模板方法模式 + 工厂方法的组合,其前提是默认逻辑本身不绑定具体产品类,且设计上明确鼓励子类重写——只要不强迫修改父类源码即可满足 OCP。
# ✅ 符合 OCP 的 Creator(抽象且可扩展)
class Creator(ABC):
@abstractmethod
def factory_method(self) -> Product:
pass
def some_operation(self) -> str:
product = self.factory_method() # 依赖抽象
return f"Creator: {
product.operation()}"
# ✅ 新增 ConcreteProductC?只需新增 ConcreteCreatorC,无需动 Creator!
class ConcreteCreatorC(Creator):
def factory_method(self) -> Product:
return ConcreteProductC()