1、概念
原型设计模式其实并不是一种设计模式,当然换句话说并不是一种解决方案,它和简单工厂模式差不多,简单工厂做个if else判断就能当作一个设计模式来讲,那么原型设计模式也可以用implement cloneable来解决。
这种做法是相当于newObject还是指向oldObject的地址,也就是说,二者实际上是一样的,未来也是一样的,随便对哪个对象进行更改,二者都会保持一致,因为可以把它们看做两个相同的“指针”;另外一种常见的做法是,重新创建一个对象,用new来实例化,这样就创建了另外一个对象,即向内存中再写入了一个对象,虽然内容一样,但地址不一样,但是这种做法费力,如果对象比较复杂的话。
原型模式在这种需求下就诞生了,我们知道Object乃一切对象的父类(超类),并且Object有一个原生的clone方法,但是该方法的调用必须要求类实现了Cloneable接口,虽然Cloneable接口只是一个摆设,里面空空荡荡,姑且就当Cloneable接口是clone方法实现的一个标志吧!我们可以创建一个类实现Cloneable即可,在覆写clone方法即可完成该类的克隆了。
浅复制,与深度复制的区别:浅复制克隆出来的对象改变可能会更改初始对象的值,深度复制克隆出来的对象与初始对象毫无关系
浅复制代码:
package yuanXing;public class Eye { private String name; public Eye(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Eye{" + "name='" + name + '\'' + '}'; }}
package yuanXing;import java.io.Serializable;public class Person implements Cloneable,Serializable { private static final long serialVersionUID = -2050795770781171788L; private String name; private String address; Eye eye; public Person(){} public Person(Eye eye){ this.eye = eye; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override protected Object clone() throws CloneNotSupportedException { return (Person) super.clone(); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", address='" + address + '\'' + ", eye=" + eye + '}'; }}
package yuanXing;public class Main { public static void main(String[] args) throws CloneNotSupportedException { Person person = new Person(new Eye("nameEyePerson")); person.setName("namePerson"); person.setAddress("addressPerson"); Person clonePerson = (Person) person.clone(); clonePerson.setName("nameEye"); clonePerson.setAddress("addressEye"); clonePerson.eye.setName("cloneEye"); System.out.println(person.toString()); System.out.println(clonePerson.toString()); System.out.println(person==clonePerson); System.out.println(person.equals(clonePerson)); System.out.println(person.getClass().equals(clonePerson.getClass())); System.out.println(person.getClass()== clonePerson.getClass()); }}
结果:
Person{name='namePerson', address='addressPerson', eye=Eye{name='cloneEye'}}
Person{name='nameEye', address='addressEye', eye=Eye{name='cloneEye'}} false false true true
深度复制:克隆出来的对象与原始对象没有关联
在person类中添加deepclone方法
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();}
main中跟换函数
package yuanXing;import java.io.IOException;public class Main { public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException { Person person = new Person(new Eye("nameEyePerson")); person.setName("namePerson"); person.setAddress("addressPerson"); //Person clonePerson = (Person) person.clone(); Person clonePerson = (Person) person.deepClone(); clonePerson.setName("nameEye"); clonePerson.setAddress("addressEye"); clonePerson.eye.setName("cloneEye"); System.out.println(person.toString()); System.out.println(clonePerson.toString()); System.out.println(person==clonePerson); System.out.println(person.equals(clonePerson)); System.out.println(person.getClass().equals(clonePerson.getClass())); System.out.println(person.getClass()== clonePerson.getClass()); }}
结果:
Person{name='namePerson', address='addressPerson', eye=Eye{name='nameEyePerson'}}
Person{name='nameEye', address='addressEye', eye=Eye{name='cloneEye'}} false false true true这就是原型设计模式的例子,目前为止没有找到项目中用到的原型设计模式,这个博客也是看了几篇博客写的,没有应用场景,如果有,后续我会慢慢写上
这个克隆就是实现Object的方法,这也是一个公司的面试题,基类Object的所有方法你用过那些。