介绍
原型模式是一种创建型的模式。原型表示该模式有一个样板实例,用户从这个样板对象中复制出一个内部属性一致的对象,被复制的实例就称为原型。原型模式多用于创复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可以使程序运行更高效。
定义
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
使用场景
- 类初始化需要消耗非常多的资源,包括数据、硬件资源等,通过原型拷贝避免这些消耗。
- 通过new产生一个对象需要非常繁琐的数据准备或访问权限,这时可以使用原型模式。
- 一个对象需要提供给其他对象访问,而且各个调用者可能需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
需要注意的是,通过实现Cloneable接口的原型模式在调用clone函数构造实例时并不一定比通过new操作速度快,只有当通过new构造对象较为耗时或者资源消耗比较大时,通过clone方法才能获得效率上的提升。因此,使用Cloneable时需要考虑构建对象的成本以及做一些效率上的测试。当然,实现原型模式也并不一定非要实现Cloneable接口,也有其他的实现方式。
UML类图
原型模式的UML类图如下:

角色介绍:
- Client:客户端用户
- Prototype:抽象类或者接口,声明具clone的能力
- ConcretePrototype:具体的原型类
实现
下面以简单的文档拷贝为例来演示一下简单的原型模式,例子中首先创建一个文档对象,即WordDocument,这个文档包括文字和图片。用户经过产时间的内容编辑后,打开该文档做进一步的编辑,但是这个文档编辑后是否被采用还不确定,因此为了安全起见,用户需要将当前文档拷贝一份,然后再在这个文档副本上进行修改。如下所示
|
|
需要注意的是,上述的例子中WordDocument的构造函数只运行了一次,通过clone拷贝对象时并不会执行构造函数!
总结
原型模式本质上是对象拷贝,容易出现的问题是深拷贝、浅拷贝。使用原型模式可以解决构建复杂对象的资源消耗问题,能够在某些场景下提升创建对象的效率。还有一个重要用途就是保护性拷贝,也就是某个对象对外可能是只读的,为了防止外部对这个只读对象修改,通过可以通过返回一个对象拷贝的形式实现只读的限制。
优点
原型模式是在内存中二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
缺点
直接在内存中拷贝时,构造函数是不会执行的,在实际开发中应该注意这个潜在的问题。