java 设计模式之原型模式(浅复制深复制)
2018-02-01 23:29
429 查看
概念:
原形模式:
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
图一 : 图二:
如图一就是浅复制结果 发现p 的对象年龄没有变化,图二深复制中p 的对象年龄却被身体stu.getPrototype().setAge(123) 改变了。说明深复制将引用对象都复制过来了。也就是对引用类型的成员变量也进行引用对象的复制。
原形模式:
原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据.
原型模式中的拷贝分为"浅拷贝"和"深拷贝":
浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.
深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.
演示:
package com.dairuijie.prototype; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思想就是将一个 对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对。在 Java 中,复制对象是通过 clone()实现的 实现深复制需要实现Serializable 可以序列化 不然没法序列化对象去进行流的输入输出 * @author DRJYY * */ public class Prototype implements Cloneable,Serializable{ /** * */ private static final long serialVersionUID = 1L; private Integer age; private String name; public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } /** * 浅复制 */ @Override protected Object clone() throws CloneNotSupportedException { /* Prototype prot = (Prototype) super.clone(); return prot;*/ return super.clone(); } /** * 深复制 * @return * @throws IOException * @throws ClassNotFoundException */ 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; ois = new ObjectInputStream(bis); return ois.readObject(); } public Prototype(Integer age, String name) { this.age = age; this.name = name; } }
package com.dairuijie.prototype; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** * 学生实体类 除了基本数据类型 同时包括Prototype 引用 方便我们测试结果 * @author DRJYY * */ public class Student implements Cloneable,Serializable{ /** * */ private static final long serialVersionUID = 1L; private Integer age; private String name; private Prototype prototype; public Prototype getPrototype() { return prototype; } public void setPrototype(Prototype prototype) { this.prototype = prototype; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public Student(Integer age, String name, Prototype prototype) { this.age = age; this.name = name; this.prototype = prototype; } 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; ois = new ObjectInputStream(bis); return ois.readObject(); } }
package com.dairuijie.prototype; import java.io.IOException; /** * * @author DRJYY * */ public class ShallowTest { public static void main(String[] args) throws ClassNotFoundException, IOException { Prototype p = new Prototype(12, "dai"); Student student = new Student(13, "dai", p); Student stu = (Student) student.deepClone(); stu.getPrototype().setAge(123); stu.setAge(11); System.out.println("原始的student的年龄----"+student.getAge()); System.out.println("克隆对象----"+stu.getAge()); System.out.println("克隆对象中的p 引用---"+stu.getPrototype().getAge()); System.err.println("p的对象原始----"+p.getAge()); } }
package com.dairuijie.prototype; public class DeepTest { public static void main(String[] args) throws CloneNotSupportedException { Prototype p = new Prototype(12, "dai"); Student student = new Student(13, "dai", p); Student stu = (Student) student.clone(); stu.getPrototype().setAge(123); stu.setAge(11); System.out.println("原始的student的年龄----"+student.getAge()); System.out.println("克隆对象----"+stu.getAge()); System.out.println("克隆对象中的p 引用---"+stu.getPrototype().getAge()); System.err.println("p的对象原始----"+p.getAge()); } }
图一 : 图二:
相关文章推荐
- 233_尚学堂_高淇_java300集最全视频教程_【GOF23设计模式】_原型模式_prototype_浅复制_深复制_反序列化实现深复制
- Rhyme/Java 设计模式之原型模式prototype通过clone方法和反序列化实现深复制
- Java设计模式_创建型_原型模式_复制对象及状态
- 设计模式之原型学习 java中的浅复制和深复制
- java设计模式---Prototype Pattern---原型模式(复制建立对象)
- 走穿java23种设计模式-5原型模式
- JAVA设计模式之 原型模式【Prototype Pattern】
- JAVA设计模式(05):创建型-原型模式(Prototype)
- Java设计模式:原型模式
- Java设计模式三(原型模式、适配器模式)
- 设计模式之九 原型模式-简历复制
- JAVA设计模式(五)——原型模式
- java设计模式笔记之原型模式
- Java设计模式——原型模式(Prototype Pattern)
- Java设计模式之从[魔兽世界副本]分析原型(Prototype)模式
- iOS与java原型设计模式对比
- 浅谈Java设计模式(五)原型模式(Prototype)
- Android的开发之&java23中设计模式------>原型模式
- JAVA设计模式(原型模式)
- Java设计模式 - 原型模式 prototype