定义:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象。
通俗理解:一个对象的产生可以不从零开始,直接从一个已经初备雏形的对象克隆,然后再修改成具体要求的对象。也就是说:生产一个人,可以不从0岁开始,而是在这个人18岁时取其DNA进行克隆,这样所有的克隆体都具备18岁的特征,然后这些克隆体根据具体需求改为特定的人。
特点:这种不通过new关键字产生一个对象,而是通过对象复制来实现的模式叫原型模式
原型模式通用类图:
原型模式的核心是实现Cloneable接口,重写Clone方法,通过该方法进行对象的拷贝。
原型模式通用源码:
public class PrototypeClass implements Cloneable {
PrototypeClass(){
System.out.println("构造函数被执行");
}
//重写Object的Clone方法
@Override
public PrototypeClass clone() {
PrototypeClass prototypeClass = null;
try {
prototypeClass = (PrototypeClass)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototypeClass;
}
}
原型模式的优点:
①性能优良:原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多。
②逃避构造函数的约束,直接在内存中拷贝,是不会执行构造函数的。
原型模式使用场景:
①资源优化场景:因原型模式的性能优良,可以在类初始化等场景使用
②性能与安全要求:new一个对象需要非常繁琐的数据准备或权限访问,因此可以使用原型模式。
③一个对象多个修改者:一个对象需要提供给其他对象访问,并且其他对象可能修改这个对象的值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
原型模式注意事项:
①构造函数不会被执行
看如下代码
public class Client {
public static void main(String[] args) {
System.out.println("进入main方法"); ----- ①
PrototypeClass prototype = new PrototypeClass(); ----- ②
System.out.println("进入Clone方法"); ----- ③
PrototypeClass prototypeClone = prototype.clone(); -----④
}
}
---------output------------
进入main方法
构造函数被执行
进入Clone方法
只有①②③有输出,第④步中的构造函数并没有被执行
Object类的Clone方法的原理是在内存中(具体来讲是堆内存)以二进制流的方式进行拷贝,重新分配一个内存块,那构造函数就不会被执行。
②深拷贝与浅拷贝问题
Object类提供的方法Clone只是拷贝本对象,其对象内部的数组,引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝叫浅拷贝。反之就是深拷贝。
③clone与final
使用clone方法,就不能在类的成员变量上增加final关键字。
参考书籍:设计模式之禅 --- 秦小波 著