设计模式:原型模式
定义
- 原型模式用于创建
给定对象的副本(拷贝)
——假设你有一个玩具,你想要制作更多完全一样的玩具(拷贝),可以使用原型模式来创建这些副本,而无需知道创建的细节。 - 原型模式涉及到一个
原型对象
,它是一个已经存在的对象。当你想要创建一个新的对象时,只需要调用这个对象的clone()
方法就可以使用这个原型对象来制作一个副本。这个副本将包含与原型对象相同的属性和方法
。你可以随后对副本进行修改,而不会影响原型对象。 - 原型模式的
clone
方法需要避免影响原型对象。
关键
- 让类实现
clone()
方法,客户基于原型实例来调用clone()
从而获得当前实例的克隆对象。 - 原型模式有两种实现方法:[[深拷贝,浅拷贝]]。浅拷贝只会复制对象中基本数据类型数据和引
用对象的内存地址,不会递归地复制引用对象,以及引用对象的引用对象……而深拷贝得到
的是一份完完全全独立的对象。所以,深拷贝比起浅拷贝来说,更加耗时,更加耗内存空
间。 - 如果要拷贝的对象是不可变对象,浅拷贝共享不可变对象是没问题的,但对于可变对象来
说,浅拷贝得到的对象和原始对象会共享部分数据,就有可能出现数据被修改的风险,也就
变得复杂多了。除非像我们今天实战中举的那个例子,需要从数据库中加载 10 万条数据并
构建散列表索引,操作非常耗时,比较推荐使用浅拷贝,否则,没有充分的理由,不要为了
一点点的性能提升而使用浅拷贝。
结构
原型模式与写时拷贝的思考
- 原型模式的
clone()
方法涉及了对于不同的[[拷贝方式]]的权衡。让我想到了之前做 xv6 实验中实现 [[copy on write fork]] 的一些体会。子进程直接拷贝父进程的内存是很低效的,因为很可能刚拷贝的内存就被 exec 加载的新程序给覆盖了,白白做无用功。 [[lazy copy]] 就是一种结合浅拷贝和深拷贝的技术,在尽量好的性能上实现较小的内存占用。