跳到主要内容

原型模式

通过声明一个包含 clone 方法的接口,原型模式将创建对象拷贝(克隆)的职责委派给对象所属的类。

结构

依照实现,可以划分为简单实现和注册表实现两种。

简单实现

原型模式简单实现示意图原型模式简单实现示意图

在简单实现中,通常会定义一个包含 clone 方法的抽象类或接口,以及具体的实现类。具体的实现类会实现 clone 方法,以便返回一个当前对象的拷贝。

clone 方法内部通常通过调用拷贝构造函数(以自身类对象为参数的构造函数)来实现创建副本对象;如果语言不支持函数重载,也可以通过一个特殊方法或是和 工厂方法 模式结合使用来实现。

注意

需要注意的是,如果具体的实现类还有子类,那么子类也需要实现 clone 方法,避免错误生成父类对象。

注册表 / 缓存实现

原型模式注册表 / 缓存实现示意图原型模式注册表 / 缓存实现示意图

在注册表实现中,会定义一个注册表类,用于存储原型对象。注册表类会提供一个方法,用于将特定的原型对象关联到固定的标识符上;此后,可以通过这个标识符来获取原型对象的拷贝。

由于存储了多个不同的原型对象,该实现又被称作缓存实现。

应用场景

  • 希望复制某个对象,但不希望复制的过程受到对象的具体类的限制

优缺点

优点

  • 克隆对象的同时而无需与它们所属的具体类相耦合
  • 可以使用一系列预生成的、 各种类型的对象作为原型,避免多次调用初始化代码
  • 可以用继承以外的方式来处理复杂对象的不同配置

缺点

  • 克隆包含循环引用的复杂对象可能会非常麻烦

代码示例

以下代码展示了一个简单的原型模式解释。要注意的是,以下代码严格来说并不是原型模式的实现,而是通过 Python 的 copy 模块实现了对象的深拷贝。

# [x] Pattern: Prototype
# Create object based on an existing object through cloning

# Why we use it
# When you want to avoid the overhead of creating a new object in the standard way (e.g., using the new keyword), and you want to create a new object based on an existing object

from copy import deepcopy
from dataclasses import dataclass


@dataclass
class Door:
width: int
height: int


def main():
door = Door(100, 200)
print(door)
door2 = deepcopy(door)
print(door2)
door2.width = 300
print(door2)
print(door)

if __name__ == '__main__':
main()