二十三种设计模式之原型模式
原型模式:
通过已拥有的一个原型类,实现Cloneable接口中的clone()方法,完成原型模式的创建。在此模式中,我们可以通过已有的一个对象实例,调用clone()方法,直接复制对象实例,就不用再重新创建对象,对对象重新进行设置,提高了效率。
注意:通过实现clone()方法,直接复制对象的实例是属于浅拷贝。
在这里说一下:
浅拷贝----->复制当前对象所有的基本类型变量,但不复制引用类型变量
深拷贝----->既复制当前对象的所有基本类型变量,同时复制该对象中的所有引用类型变量
代码实现:
public class realizeType implements Cloneable{
/**
* 原型模式:通过已拥有的一个原型类,实现Cloneable接口中的clone()方法,完成原型模式的创建
* 在此模式中,我们可以通过已有的一个对象实例,调用clone()方法,直接复制对象实例,就不用再重新创建对象,
* 对对象重新进行设置,提高了效率
*
* 原型模式 ----> 进行的是浅克隆("浅克隆"不会复制该对象中引用的其他对象 -----> 仅仅克隆基本类型变量,而不克隆引用类型的变量)
* 扩展:"深克隆"既克隆基本类型变量,也克隆引用类型变量
*
* 适应环境: 1.需要多个对象实例
* 2.多个对象实例之间,相似度较高
* 3.进行对象创建相比较直接复制对象比较麻烦
* 优点:能够高效的创建对象,不需要知道创建对象过程中的具体细节
*/
String name;
String sex;
String IDcard;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getIDcard() {
return IDcard;
}
public void setIDcard(String iDcard) {
IDcard = iDcard;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "[" + name + "]" + "\t[" + sex + "]" + "\t[" + age + "]" + "\t[" + IDcard + "]";
}
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
System.out.println("复制成功!");
return (realizeType)super.clone();
}
}
这里让我们看一下运行的结果
首先编写一下测试类
public class test {
public static void main(String[] args) {
realizeType rt1 = new realizeType();
realizeType rt2 = null;
rt1.setName("呵呵");
rt1.setSex("男");
rt1.setIDcard("620105199901011032");
rt1.setAge(10);
try {
rt2 = (realizeType) rt1.clone();
rt2.setName("哈哈");
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(rt1.toString());
System.out.println(rt2.toString());
System.out.println(rt1.hashCode());
System.out.println(rt2.hashCode());
}
}
运行结果如下:
通过两个hashCode比较我们可以发现,原型对象和复制完成之后的对象的hashCode是不同的
再来看下浅拷贝的问题:
修改一下原型类,添加一个ArrayList的对象
ArrayList list = new ArrayList();
在测试类中看一下原型对象和复制之后的对象调用list对象的hashCode的值有何不同
这里我们可以看出2个对象调用list实例的hashCode值是一样的,这就充分说明了浅拷贝不能够复制原型对象中引用类型数据的问题。