Prototype Pattern
来源:互联网 发布:动易cms 报价 编辑:程序博客网 时间:2024/06/08 02:47
在软件开发中,有时候可能会需要创建一些特别复杂的对象,如果系统中已经存在同样类型的对象,并且不同的属性个数相差不大的话,用Prototype模式可能是一个理想的选择。
定义 :用原型实例指定创建物件的种类,并且通过拷贝这些原型创建新的物件。
Prototype 模式允许一个物件再创建另外一个可定制的物件,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型物件传给那个要发动创建的物件,这个要发动创建的物件通过请求原型物件拷贝它们自己来实施创建。
使用方法很简单,只要调用对象的clone方法返回一个新的对象就可以了。但是为什么没有其他新的方法来实现这个模式呢?因为Java中的Object提供了clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单.
在这个clone方法中,我们只要调用Object的克隆方法返回一个对象,就可以以最简单的方式实现Prototype模式。
在其他编程语言中,就需要创建一个当前类的新的对象,然后把当前对象本身的各属性的值复制一份给新创建的对象,并且返回新对象即可。
什么时候应该使用prototype模式呢?
1.当你要创建的对象与现有运行时对象相似度很大时
2.为了避免创建类的工厂类导致层次复杂度增加时
3.当类的实例只有不多的几种状态时(此时需要引进原型管理器)
Prototype模式常用在一些对象管理器中。这些对象管理器本身一般为单例模式,主要负责对象的创建和返回。由于返回的对象的类型基本上是一致的,而且返回的对象的各项属性大多保持一致,只有极少数属性才需要修改,所以用Prototype无疑是极好的选择。
2、深拷贝和浅拷贝(调用父类的clone即可实现浅拷贝,注意返回类型为object,如果需要深度拷贝,则需要流化合反流化)
需要注意的是:浅拷贝和深拷贝的区别。
简单的讲,浅拷贝就是只对当前对象的直属属性进行复制,如果其属性是基本类型的话,就复制原对象的值;如果其属性是其他对象的话,就复制对象的地址。而深拷贝则是麻烦的多,如果其属性是对象的话,就需要创建一个新的子属性的对象,并且对这个对象的各项属性进行复制,如果子属性还有子属性的话,则需要递归的进行复制操作。
一切就看需求,如果那些属性的值不会被变更的话,那么只需要实现浅拷贝即可;否则,深拷贝就是必须的
java里的clone分为:
A:浅复制(浅克隆): 浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
b:深复制(深克隆):深复制把要复制的对象所引用的对象都复制了一遍。
Java中对象的克隆,为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。必须要遵循下面三点
1.在派生类中覆盖基类的clone()方法,并声明为public【Object类中的clone()方法为protected的】。
2.在派生类的clone()方法中,调用super.clone()。
3.在派生类中实现Cloneable接口。
* @see java.lang.Cloneable */ protected native Object clone() throws CloneNotSupportedException; /**
Object类里的clone方法是浅复制(浅克隆)
利用序列化来做深复制,把对象写到流里的过程是序列化(Serilization)过程,而把对象从流中读出来的过程则叫做反序列化(Deserialization)过程。应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面。,利用这个特性,可以做深拷贝
利用流进行深拷贝,例:
//集合深拷贝
public Object clone(){ try {//流化 ByteArrayOutputStream ot = new ByteArrayOutputStream(); ObjectOutputStream oo = new ObjectOutputStream(ot); oo.writeObject(this); //反流化 ByteArrayInputStream it = new ByteArrayInputStream(ot.toByteArray()); ObjectInputStream oi = new ObjectInputStream(it); return (oi.readObject()); } catch (IOException e) { e.printStackTrace(); return null; } catch (ClassNotFoundException e) { e.printStackTrace(); return null; } }
3、个人测试举例
浅拷贝:
package prototype;/** * 原型模式 * @author hanrk-2734 * */public class MyClone implements Cloneable {private String a="myclone";private Student student=new Student();//访问域是否必须改为public 最好改为publicprotected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stubreturn super.clone();}public String getA() {return a;}public void setA(String a) {this.a = a;}public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}}
package prototype;public class Student {private String name="kerry";public String getName() {return name;}public void setName(String name) {this.name = name;}}
package prototype;/** * 测试克隆 * @author hanrk-2734 * */public class TestClone {public static void main(String[] args) throws CloneNotSupportedException {MyClone myClone=new MyClone();System.out.println("myclone:"+myClone.getA());MyClone myClone2=(MyClone) myClone.clone();System.out.println("myclone2:"+myClone2.getA());/** * 浅拷贝输出结果,对象(非基本数据类型)为内存地址,相等表示同一个对象,对象未被复制 * myclone:myclone myclone2:myclone student:prototype.Student@de6ced student:prototype.Student@de6ced */System.out.println("student:"+myClone.getStudent());System.out.println("student:"+myClone2.getStudent());}}
深拷贝
package 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;/** * 原型模式 * @author hanrk-2734 * */public class MyClone implements Cloneable ,Serializable{private String a="myclone";private Student student=new Student();//访问域是否必须改为public 最好改为publicprotected Object clone() throws CloneNotSupportedException {// TODO Auto-generated method stub//return super.clone();//深度拷贝:第一 复写克隆逻辑,改为流化和反流化;第二:非基本类型对象必须实现接口Serializable;第三类本身实现SerializableObject resultObject=null; ByteArrayOutputStream ot = new ByteArrayOutputStream(); ObjectOutputStream oo = null;try {oo = new ObjectOutputStream(ot);} catch (IOException e2) {// TODO Auto-generated catch blocke2.printStackTrace();} try {oo.writeObject(this);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} ByteArrayInputStream it = new ByteArrayInputStream(ot.toByteArray()); ObjectInputStream oi = null;try {oi = new ObjectInputStream(it);} catch (IOException e1) {// TODO Auto-generated catch blocke1.printStackTrace();} try {return resultObject=oi.readObject();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} return resultObject;}public String getA() {return a;}public void setA(String a) {this.a = a;}public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}}
package prototype;import java.io.Serializable;public class Student implements Serializable {private String name="kerry";public String getName() {return name;}public void setName(String name) {this.name = name;}}
package prototype;/** * 测试克隆 * @author hanrk-2734 * */public class TestClone {public static void main(String[] args) throws CloneNotSupportedException {MyClone myClone=new MyClone();System.out.println("myclone:"+myClone.getA());MyClone myClone2=(MyClone) myClone.clone();System.out.println("myclone2:"+myClone2.getA());/** * 浅拷贝输出结果,对象(非基本数据类型)为内存地址 * myclone:myclone myclone2:myclone student:prototype.Student@de6ced student:prototype.Student@de6ced *//** * 深拷贝结果,student内存地址不同,对象被成功复制 * myclone:myclone myclone2:myclone student:prototype.Student@89ae9e student:prototype.Student@1d58aae */System.out.println("student:"+myClone.getStudent());System.out.println("student:"+myClone2.getStudent());}}
- Prototype Pattern
- prototype pattern
- Prototype Pattern
- [Design Pattern]:Prototype
- 原型模式(Prototype Pattern)
- 原型模式(Prototype Pattern)
- 原型模式(Prototype Pattern)
- 原型模式 Prototype Pattern
- 原型模式 Prototype Pattern
- Prototype Design Pattern
- Design Pattern-Prototype
- 原型模式(Prototype Pattern)
- java design pattern -- prototype
- 原型模式( Prototype Pattern)
- 原型模式【PROTOTYPE PATTERN 】
- 原型模式(prototype pattern)
- Design Pattern :Prototype
- 原型模式(Prototype Pattern)
- CMOS跳线短接后,开机密码仍存在解决方法
- linux Chmod 使用
- android 加载图片轻松避免OOM(out of memory) 支持设置缓存大小,不再强制catch OOM
- 当你扛不住的时候就读一遍,其实人在最痛苦的时候意味着马上成功。
- 在GitHub上分享和展示你的代码
- Prototype Pattern
- 中国软件服务外包IT公司最新排名-IT外包最强前50名
- 获取视频第一帧
- 线程与进程的区别
- aapt命令详解
- sql CTE简介
- A*算法入门
- LINK:warning LINK4098: defaultlib "LIBC" conflicts with use of other libs; use /NODEFAULTLIB:library
- 新浪微创投狩猎季:5家LP皆VC大佬 人气日渐高涨