原型模式
设计原则:无
常用场景:需要在运行时动态的创建指定实例种类的对象,或是需要复用其状态
使用概率:10%
复杂度:中低
变化点:无
选择关键点:创建出来的对象是否可以立即投入使用
逆鳞:在以为是深度拷贝的情况下,却未实现深度拷贝
主要思想
其实一个对象多new就是原型,即每次都用新的对象
注意生成新对象,可以用new也可以进行克隆 new会有一系列编译、创建内存等过程 比直接进行克隆创建复制内存空间效率要低
实现克隆 java实现Cloneable接口就可以了
但是要注意直接clone 是浅克隆
即成员变量 基本类型会复制值,引用类型还是前一个对象的成员变量引用地址没变 所以是浅复制
实现深复制两种方案
1.覆盖clone方法 在方法中自己再初始化引用类型的成员变量
2.实现序列化接口 进行一次正反序列化 反序列化出来的对象引用类型的成员变量也会初始化过的
浅复制:
public class Prototype implements Cloneable { public int a = 1;public Date time = new Date(); @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
public static void main(String[] args) throws CloneNotSupportedException { Prototype prototype = new Prototype(); System.out.println(prototype); Prototype prototypeClone = (Prototype) prototype.clone(); System.out.println(prototypeClone); System.out.println(prototypeClone.a); System.out.println(prototypeClone.time==prototype.time); }
结果
Prototype@33e5ccce //对象不同 Prototype@5a42bbf4 1 true //引用相同
深复制1:
protected Object clone() throws CloneNotSupportedException { Prototype obj= (Prototype) super.clone(); obj.time= (Date) this.time.clone(); return obj; } Prototype@33e5ccce Prototype@5a42bbf4 1 false //引用不同
深复制2:
public Object deepClone() throws IOException, ClassNotFoundException { /* 写入当前对象的二进制流 */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); /* 读出二进制流产生的新对象 */ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } Prototype@33e5ccce Prototype@614c5515 1 false //引用不同