原型模式(Prototype)
使用场景:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。通过new产生一个对象需要非常繁琐的数据准备或访问权限。
特点:
1,实现 Cloneable 接口
2,重写 Object clone 方法
3,深拷贝,浅拷贝 会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。
其余的都是浅拷贝。(引用类型拷贝是复制指针,其实复制对象和原对象都是指向同一个引用)
UML类图:
代码:
/**
* 1,实现 Cloneable 接口
* 2,重写 Object clone 方法
* 3,深拷贝,浅拷贝 会发生深拷贝的有java中的8中基本类型以及他们的封装类型,另外还有String类型。
* 其余的都是浅拷贝。(引用类型拷贝是复制指针,其实复制对象和原对象都是指向同一个引用)
*/
public class Prototype implements Cloneable{
public String name="prototype";
public Integer age = new Integer(12);
public char flag = 'a';
public ArrayList list = new ArrayList();
public Child child = new Child();
@Override
public Object clone() {
Prototype prototype = null;
try {
prototype = (Prototype) super.clone();
//对引用类型进行深度拷贝 ArrayList本身已经实现了Cloneable接口
prototype.list = (ArrayList)prototype.list.clone();
prototype.child = new Child();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return prototype;
}
}
public class ConcretePrototype extends Prototype {
public void show(){
System.out.println("原型模式");
}
}
public class Child { public String name = "child prototype"; }
public class PrototypeTest { public static void main(String[] args) { ConcretePrototype concretePrototype = new ConcretePrototype(); ConcretePrototype clone1 = (ConcretePrototype) concretePrototype.clone(); clone1.name="name change"; clone1.age=15; clone1.flag='b'; clone1.list.add("sss"); clone1.child.name = "child name change"; System.out.println((concretePrototype.name==clone1.name)+"| concretePrototype.name="+concretePrototype.name+"| clone1.name="+clone1.name); System.out.println((concretePrototype.age==clone1.age)+"| concretePrototype.age="+concretePrototype.age+"| clone1.age="+clone1.age); System.out.println((concretePrototype.flag==clone1.flag)+"| concretePrototype.flag="+concretePrototype.flag+"| clone1.flag="+clone1.flag); System.out.println((concretePrototype.list==clone1.list)+"| concretePrototype.list="+concretePrototype.list+"| clone1.list="+clone1.list); System.out.println((concretePrototype.child==clone1.child)+"| concretePrototype.child="+concretePrototype.child.name+"| clone1.child="+clone1.child.name); } }