原型模式的官方定义:
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
大白话:
现在有一个类,它要产生大量的对象,而且这些对象中的属性值大部分都相同;如果我们要获取这样一个对象的时候每次都通过new,然后再set每一个属性值,那么这样就太麻烦了。这种情况下使用原型模式非常便捷:
我们让这个类去实现ICloneable接口,并且实现该接口的clone()函数,在clone函数中让当前对象进行一次浅拷贝/深拷贝,总之就是克隆一个当前对象来,这样我们就无需new完了对象后再逐个set属性了。
原型模式的类图:
如果一个类要使得调用者能够克隆,那在定义这个类的时候就需要让它实现ICloneable接口,并实现clone函数,在函数中实现当前对象的浅拷贝或深拷贝。
客户端拿到这个类后,如果需要克隆对象,调用这个类的clone函数即可。
深拷贝和浅拷贝:
浅拷贝:将对象中基本数据类型的值复制到新的对象中去,若对象中有引用类型的属性,则将引用复制给新对象,此时,新旧对象中引用类型的指针都指向同一个对象。
如上图所示:新对象中的phone是基本数据类型,它的值是旧对象中直接复制过来的;而新对象中的Person是引用类型,它和旧对象中的Perosn都指向同一个Person对象。
深拷贝:深拷贝和浅拷贝对于基本数据类型都是一样复制,不同之处在于:浅拷贝之后新旧对象中的引用类型的变量都指向同一个对象,而深拷贝当遇到引用类型的对象时,再new一个对象,新对象中的引用类型变量指向新创建的对象,如下图所示:
使用深拷贝实现原型模式:
如上图所示,原型类中有引用类型的成员变量Person,并且Person类中有引用类型的成员变量Work,要实现深拷贝,要使得原型类、Person类、Work类中的clone函数都要实现深拷贝的功能,实现深拷贝的clone函数如下:
public Object clone(){
//将当前对象进行一次浅拷贝
原型 p = this.clone();
//将当前对象中引用类型的变量进行一次深拷贝。由于Person类也实现了ICloneable接口,并且clone函数也进行了一样的操作,调用Work类的clone函数,由于Work类中全都是基本数据类型,所以Work类不需要实现ICloneable接口,对Work类的克隆仅需要Object提供的clone()函数进行浅拷贝即可。
p.setPerson(this.person.clone());
return p;
}
Java中的clone函数:
Java中的Object类中就有clone()函数,并且这个函数是对对象进行浅拷贝。当我们需要对一个对象进行深拷贝的时候,就必须要让这个类实现Cloneable接口,并且重写clone()函数。
Java中的深拷贝和浅拷贝请移步至:http://blog.csdn.net/shootyou/article/details/3945221