定义
原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式主要适用于以下场景:
1、类初始化消耗资源较多。
2、new 产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)。
3、构造函数比较复杂。
4、循环体中生产大量对象时。
通俗理解
1、细胞分裂的过程,一个细胞的有丝分裂产生两个相同的细胞。
2、西游记中孙悟空变出后孙的本领。
3、火影忍者中鸣人的隐分身忍术。
java中的浅克隆
package com.tcp;
import java.util.ArrayList;
public class Realizetype implements Cloneable {
public int id;
public String name;
public ArrayList<String> arrayList = new ArrayList<>();
@Override
protected Object clone() throws CloneNotSupportedException {
return (Realizetype)super.clone();
}
public static void main(String[] args) throws Exception {
Realizetype s1 = new Realizetype();
s1.id=1;
s1.name = "say";
s1.arrayList.add("1111");
Realizetype s2 = (Realizetype)s1.clone();
System.out.println("s1->arrayList:"+s1.arrayList+",id:"+s1.id+",name:"+s1.name);
System.out.println("s2->arrayList:"+s2.arrayList+",id:"+s2.id+",name:"+s2.name);
s1.id=2;
s2.name="hello";
s2.arrayList.add("2222");
System.out.println("s1->arrayList:"+s1.arrayList+",id:"+s1.id+",name:"+s1.name);
System.out.println("s2->arrayList:"+s2.arrayList+",id:"+s2.id+",name:"+s2.name);
}
}
执行结果:
结论
java中的克隆是浅克隆,对基本类型没有影响,引用类型有影响,就像上面的结果一样,修改ArrayList的值以后两个对象都变了,等于是引用对象仍然指向原来的对象。
深克隆
实现一
package com.tcp;
import java.util.ArrayList;
public class Realizetype implements Cloneable {
public int id;
public String name;
public ArrayList<String> arrayList = new ArrayList<>();
@Override
protected Object clone() throws CloneNotSupportedException {
Realizetype realizetype = (Realizetype)super.clone();
realizetype.arrayList = (ArrayList<String>) realizetype.arrayList.clone();
return realizetype;
}
public static void main(String[] args) throws Exception {
Realizetype s1 = new Realizetype();
s1.id=1;
s1.name = "say";
s1.arrayList.add("1111");
Realizetype s2 = (Realizetype)s1.clone();
System.out.println("s1->arrayList:"+s1.arrayList+",id:"+s1.id+",name:"+s1.name);
System.out.println("s2->arrayList:"+s2.arrayList+",id:"+s2.id+",name:"+s2.name);
s1.id=2;
s2.name="hello";
s2.arrayList.add("2222");
System.out.println("s1->arrayList:"+s1.arrayList+",id:"+s1.id+",name:"+s1.name);
System.out.println("s2->arrayList:"+s2.arrayList+",id:"+s2.id+",name:"+s2.name);
}
}
执行结果:
从结果可以看出两个对象的修改不会进行相互影响。
实现二
package com.tcp;
import java.io.*;
import java.util.ArrayList;
public class Realizetype implements Cloneable, Serializable {
public int id;
public String name;
public ArrayList<String> arrayList = new ArrayList<>();
@Override
protected Object clone() throws CloneNotSupportedException {
return this.deepClone();
}
public Object deepClone(){
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
Realizetype realizetype = (Realizetype)ois.readObject();
return realizetype;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void main(String[] args) throws Exception {
Realizetype s1 = new Realizetype();
s1.id=1;
s1.name = "say";
s1.arrayList.add("1111");
Realizetype s2 = (Realizetype)s1.clone();
System.out.println("s1->arrayList:"+s1.arrayList+",id:"+s1.id+",name:"+s1.name);
System.out.println("s2->arrayList:"+s2.arrayList+",id:"+s2.id+",name:"+s2.name);
s1.id=2;
s2.name="hello";
s2.arrayList.add("2222");
System.out.println("s1->arrayList:"+s1.arrayList+",id:"+s1.id+",name:"+s1.name);
System.out.println("s2->arrayList:"+s2.arrayList+",id:"+s2.id+",name:"+s2.name);
}
}
执行结果: