定义:通过创建一个原型对象,然后拷贝该原型对象来创建新的对象,新的对象与原型实例类型一致。
特点:
创建型类型设计模式克隆对象不调用构造函数,不需要知道对象创建细节原型克隆出的对象比直接new的对象性能高,因为克隆对象调用Object的clone方法,该方法直接调用native层的clone方法,拷贝内存中的二进制流,所以要比直接new对象性能高。
缺点:
必须配备克隆方法,需要实现Cloneable接口,重写clone方法;需要注意浅拷贝、深拷贝问题:Object类的clone方法只会拷贝对象中的基本的数据类型,对于数组、容器对象、引用对象等都不会拷贝,这就是浅拷贝。如果要实现深拷贝,必须将原型模式中的数组、容器对象、引用对象等另行拷贝;会破坏单例模式,原型模式允许克隆对象,所以单例模式和原型模式是相对的;
应用场景
原型模式主要用于对象的复制,所以这种模式的适应场景是:
new一个对象需要繁琐的过程,比如要传多个参数,初始化一些变量等创建的是一个大对象,类初始化需要消耗大量资源
一般遍历循环创建一个对象时,就可以使用原型模式,下面使用一个示例实现一下原型模式:
代码实现1、一般使用先创建一个抽象类,实现Cloneable接口,重写clone方法,代码如下:
public abstract class ACar implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
2、创建Car类继承父类,并且实现clone方法,代码如下:
public class Car extends ACar{
private int name;
private String engine;
private String wheel;
private String cpu;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// 省略get、set方法
}
测试程序
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
ACar car = new Car();
for (int i = 0; i < 10; i++) {
Car clone = (Car) car.clone();
clone.setName(i);
clone.setEngine("volvo");
clone.setCpu("麒麟");
clone.setWheel("四轮");
System.out.println(clone.getName() + ":" + clone);
}
}
}
打印结果显示会创建不同的对象:
0:com.design.pattern.prototype.Car@6e0be858 1:com.design.pattern.prototype.Car@61bbe9ba 2:com.design.pattern.prototype.Car@610455d6 3:com.design.pattern.prototype.Car@511d50c0 4:com.design.pattern.prototype.Car@60e53b93 5:com.design.pattern.prototype.Car@5e2de80c 6:com.design.pattern.prototype.Car@1d44bcfa 7:com.design.pattern.prototype.Car@266474c2 8:com.design.pattern.prototype.Car@6f94fa3e 9:com.design.pattern.prototype.Car@5e481248开源库中的应用
原型设计模式在JDK和许多开源库中经常使用,下面简单举个例子:
ArrayList类
// 实现Cloneable接口 public class ArrayListextends AbstractList implements List , RandomAccess, Cloneable, java.io.Serializable // 重写clone方法 public Object clone() { try { ArrayList> v = (ArrayList>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } }
Date类
// 实现Cloneable接口
public class Date
implements java.io.Serializable, Cloneable, Comparable
// 重写clone方法
public Object clone() {
Date d = null;
try {
d = (Date)super.clone();
if (cdate != null) {
d.cdate = (baseCalendar.Date) cdate.clone();
}
} catch (CloneNotSupportedException e) {} // Won't happen
return d;
}
深克隆和浅克隆问题
Object的clone方法默认是浅克隆方式,浅克隆只会克隆基本数据类型,集合类中都实现了Cloneable接口,所以集合类也会被克隆,而引用类型Date或者其他对象则需要使用深拷贝。
private Date date;
@Override
protected Object clone() throws CloneNotSupportedException {
Car clone = (Car) super.clone();
// 深克隆,调用Date类的clone方法,如果是自己创建的类,需要自己实现类的深clone方法
clone.date = (Date) clone.date.clone();
return clone;
}
示例代码:prototype
个人公众号,喜欢的可以关注一下:



