原型模式(Prototype)

在前面的几种创建型模式中(工厂、抽象工厂、建造者),

我们解决的核心问题都是:

"对象该怎么创建?"

而原型模式关注的是另一件事:

"对象已经很复杂了,能不能直接复制一个?"

这就是 Prototype(原型)模式 要解决的问题。


一、原型模式要解决什么问题?

原型模式的核心思想一句话就够了:

通过复制已有对象来创建新对象,而不是通过 new 或构造函数。

它适合解决这类场景:

  • 对象创建成本很高(初始化复杂、耗时)
  • 对象结构复杂,构造参数多
  • 需要大量相似对象,只在少量属性上不同
  • 希望避免大量重复的初始化逻辑

二、一个"很痛苦"的对象创建例子

先看一个不使用原型模式的写法。

python 复制代码
class Report:
    def __init__(self):
        self.title = ""
        self.header = ""
        self.body = ""
        self.footer = ""
        self.styles = {}
        self.permissions = []

    def generate(self):
        print(f"Generate report: {self.title}")

如果每次创建报告,都要这样:

python 复制代码
r1 = Report()
r1.title = "Sales Report"
r1.header = "Company Header"
r1.body = "Sales Data"
r1.footer = "Company Footer"
r1.styles = {"font": "Arial"}
r1.permissions = ["admin", "manager"]

再来一个几乎一样的:

python 复制代码
r2 = Report()
r2.title = "Inventory Report"
r2.header = "Company Header"
r2.body = "Inventory Data"
r2.footer = "Company Footer"
r2.styles = {"font": "Arial"}
r2.permissions = ["admin", "manager"]

问题非常明显:

  • 大量重复初始化代码
  • 很容易漏字段、写错字段
  • 一旦结构调整,所有创建逻辑都要改

三、原型模式的核心思想

原型模式不是"从零创建",而是:

  1. 先准备一个原型对象
  2. 通过拷贝原型来创建新对象
  3. 再对差异部分进行修改

这在 Python 里天然就很顺手。


四、Python 中实现原型模式的关键工具

1️⃣ 浅拷贝与深拷贝

Python 标准库已经帮你准备好了:

python 复制代码
import copy
  • copy.copy() → 浅拷贝
  • copy.deepcopy() → 深拷贝

这是原型模式在 Python 中最常见的实现方式。


五、使用原型模式重构示例

1️⃣ 定义一个原型对象

python 复制代码
import copy

class Report:
    def __init__(self, title):
        self.title = title
        self.header = "Company Header"
        self.body = ""
        self.footer = "Company Footer"
        self.styles = {"font": "Arial"}
        self.permissions = ["admin", "manager"]

    def clone(self):
        return copy.deepcopy(self)

    def generate(self):
        print(f"Generate report: {self.title}")

2️⃣ 创建原型

python 复制代码
base_report = Report("Base Report")

3️⃣ 基于原型复制新对象

python 复制代码
sales_report = base_report.clone()
sales_report.title = "Sales Report"
sales_report.body = "Sales Data"

inventory_report = base_report.clone()
inventory_report.title = "Inventory Report"
inventory_report.body = "Inventory Data"

4️⃣ 使用

python 复制代码
sales_report.generate()
inventory_report.generate()

六、为什么一定要用 deepcopy

看这个例子:

python 复制代码
r1 = base_report.clone()
r2 = base_report.clone()

r1.permissions.append("guest")

如果你用了 浅拷贝

  • r1.permissions
  • r2.permissions
  • base_report.permissions

很可能指向的是同一个列表对象

这会导致非常隐蔽的 bug。

所以经验法则是:

原型模式中,除非你非常确定,否则优先使用 deepcopy


七、原型注册表(Prototype Registry)

在复杂系统中,通常不止一个原型。

可以用一个"原型仓库"来统一管理。

python 复制代码
class PrototypeRegistry:
    def __init__(self):
        self._prototypes = {}

    def register(self, name, prototype):
        self._prototypes[name] = prototype

    def clone(self, name):
        return self._prototypes[name].clone()

使用方式:

python 复制代码
registry = PrototypeRegistry()

registry.register("base_report", base_report)

r = registry.clone("base_report")
r.title = "Custom Report"

八、原型模式的优缺点

✅ 优点

  • 避免复杂、重复的构造逻辑
  • 创建对象速度快
  • 对象结构变化时,修改成本低
  • 非常适合 Python 的动态特性

❌ 缺点

  • 深拷贝可能有性能开销
  • 对象之间的引用关系复杂时,调试成本高
  • 不恰当使用浅拷贝容易引发隐藏 bug

九、原型模式适合用在什么地方?

非常适合以下场景:

  • 模板对象、配置对象
  • 报表、文档、表单生成
  • 游戏中的角色、技能、道具
  • UI 组件复制
  • 需要"从现有状态复制"的对象

十、一句话总结

原型模式的本质不是"设计得多高大上",
而是让你:
少写构造代码,少踩初始化的坑。

在 Python 中:

  • copy.deepcopy
  • 再加一个 clone() 方法

就已经是一个非常地道、实用的原型模式实现了。

相关推荐
dFObBIMmai17 小时前
CSS如何检测页面浮动元素位置_使用审查工具与clear
jvm·数据库·python
qq_4609784017 小时前
实现 Svelte 中基于数组索引的 details 元素单开单关交互
jvm·数据库·python
A-Jie-Y17 小时前
JAVA设计模式-抽象工厂模式
java·设计模式
AI科技星17 小时前
ELN 升级:π 级数自动生成器全域数理架构
大数据·人工智能·python·算法·金融
用户93520139867918 小时前
淘宝开放平台 item_cat_get 接口详解:获取淘宝商品类目
python
dfdfadffa18 小时前
SQL窗口函数如何优化嵌套子查询_提升执行效率
jvm·数据库·python
时空系18 小时前
第6篇:多维数据盒——管理大量数据 python中文编程
开发语言·python·ai编程
故事还在继续吗18 小时前
设计模式完全指南
设计模式
小敬爱吃饭18 小时前
知识图谱实战第一章:知识图谱全景解析其定义、技术演进与十大应用场景
人工智能·python·目标检测·自然语言处理·flask·nlp·知识图谱