定义
原型模式(Prototype Pattern)的简单程度仅次于单例模式和迭代器模式。正是由于简单,使用场景才非常多,其定义如下:
Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模型的核心是一个clone方法,通过该方法进行对象的拷贝,Java提供了一个Cloneable接口来标示这个对象是可拷贝的。
JDK中,Cloneable是一个方法都没有的,这个接口只是一个标记作用,在JVM中具有这个标记的对象才有可能被拷贝。
原型模式的通用类图:
![](https://img.haomeiwen.com/i6555006/84f91ac8718ef906.png)
原型模式的通用代码
public class PrototypeClass implements Cloneable {
// 覆写父类Object方法
@Override
public PrototypeClass clone() {
PrototypeClass prototypeClass = null;
try {
prototypeClass = (PrototypeClass)super.clone();
} catch (Exception e) {
// 异常处理
}
}
}
应用
原型模型的优点
-
性能优良
原型模型是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点 -
逃避构造函数的约束
这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的。优点就是减少了约束,缺点也是减少了约束,需要大家在实际应用时考虑。
原型模式的使用场景
-
资源优化场景
类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。 -
性能和安全要求的场景
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。 -
一个对象多个修改者的场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
原型模式的注意事项
原型模式虽然简单,但是在Java中使用原型模式也就是clone方法还有一些注意事项的。
-
构造函数不会被执行
我们以实例说明:
public class SomeThing implements Cloneable {
public SomeThing() {
System.out.print("构造函数被执行了~~~");
}
@Override
protected SomeThing clone() {
SomeThing thing = null;
try {
thing = (SomeThing) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return thing;
}
public static void main(String[] args) {
// 产生一个对象
SomeThing thing = new SomeThing();
// 拷贝一个对象
SomeThing cloneThing = thing.clone();
}
}
执行结果为:
构造函数被执行了~~~
-
浅拷贝和深拷贝
Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝
。
使用原型模型时,引用的成员变量必须满足两个条件才不会被拷贝:
一、类的成员变量,而不是方法内变量;
二、必须是一个不可变的引用对象,而不是一个原始类型或不可变对象。
网友评论