Java设计模式4-原型模式
来源:互联网 发布:oa系统的数据库设计 编辑:程序博客网 时间:2024/06/12 18:38
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
说白了就是一个类实现了Cloneable,重写clone方法,就可以调用这个类的对象复制实例了。
1、拷贝分类
原型模式中的拷贝分为"浅拷贝"和"深拷贝":浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
2、浅拷贝演示1
a.定义一个Prototype类
public class Prototype implements Cloneable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } }
b.使用
public class TestMain { public static void main(String[] args) { testPrototype(); } private static void testPrototype(){ Prototype pro = new Prototype(); pro.setName("original object"); Prototype pro1 = (Prototype)pro.clone(); pro.setName("changed object"); System.out.println("original object:" + pro.getName()); System.out.println("cloned object:" + pro1.getName()); } } 结果: original object:changed object cloned object:original object
3、浅拷贝演示2
我们定义一个Prototype类,不去实现Cloneable接口,看看这个类里面的属性能不能被复制(答案是不能的)a.我们定义一个Prototype类,不去实现Cloneable接口
public class Prototype{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
b.定义一个NewPrototype,实现Cloneable接口
public class NewPrototype implements Cloneable { private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } //将上面的类作为这个类的一个属性,看看能不能clone private Prototype prototype; public Prototype getPrototype() { return prototype; } public void setPrototype(Prototype prototype) { this.prototype = prototype; } public Object clone(){ try { return super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } }
c.测试使用
public class TestMain { public static void main(String[] args) { testPrototype(); } private static void testPrototype(){ Prototype pro = new Prototype(); pro.setName("original object"); NewPrototype newObj = new NewPrototype(); newObj.setId("test1"); newObj.setPrototype(pro); NewPrototype copyObj = (NewPrototype)newObj.clone(); copyObj.setId("testCopy"); //这个copyObj对象里面的属性prototype是没有复制的,指向的是同一个对象 copyObj.getPrototype().setName("changed object"); System.out.println("original object id:" + newObj.getId()); System.out.println("original object name:" + newObj.getPrototype().getName()); System.out.println("cloned object id:" + copyObj.getId()); System.out.println("cloned object name:" + copyObj.getPrototype().getName()); } } 结果: original object id:test1 original object name:changed object //已经改变了原来的值了 cloned object id:testCopy cloned object name:changed object
可以看出来,不实现Cloneable的类属性是不能被复制的。如果要prototype这个属性也被复制,只要Prototype这个类实现Clonbeable接口就行。
4、深拷贝
利用串行化来做深复制把对象写道流里的过程是串行化(Serilization)过程;把对象从流中读出来是并行化(Deserialization)过程. 写在流里的是对象的一个拷贝,然后再从流里读出来重建对象.a.创建一个PrototypeSe类,实现Serializable序列化接口
public class PrototypeSe implements Serializable { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
b.创建一个NewPrototypeSe,同样实现Serializable接口
public class NewPrototypeSe implements Serializable { private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } private PrototypeSe prototype; public PrototypeSe getPrototype() { return prototype; } public void setPrototype(PrototypeSe prototype) { this.prototype = prototype; } public Object deepClone(){ try { ByteArrayOutputStream bo = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(bo); oo.writeObject(this); ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi = new ObjectInputStream(bi); return oi.readObject(); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return null; } } }
c.使用
public class TestDeepClone { public static void main(String[] args) { PrototypeSe po = new PrototypeSe(); po.setName("test1"); NewPrototypeSe se = new NewPrototypeSe(); se.setPrototype(po); NewPrototypeSe deepClone = (NewPrototypeSe)se.deepClone(); deepClone.getPrototype().setName("test2"); System.out.println("original name:" + se.getPrototype().getName()); System.out.println("cloned name:" + deepClone.getPrototype().getName()); } } 结果: original name:test1 cloned name:test2
注意:原型类并没有实现Cloneable接口,而是自己定义一个deepClone方法复制
阅读全文