2014-02-14 11:27:33

声明:本文不仅是本人自己的成果,有些东西取自网上各位大神的思想,虽不能一一列出,但在此一并感谢!

原型模式,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。在Java中,复制对象是通过clone()实现的,调用的是Object的clone()方法,而在Object类中,clone()是native的。在这儿,我将结合对象的浅复制和深复制来说一下,首先需要了解对象深、浅复制的概念:

浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。

深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

此处,写一个深、浅复制的例子:

Prototype.java

  1. package com.david.prototype;
  2.  
  3. import java.io.ByteArrayInputStream;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.IOException;
  6. import java.io.ObjectInputStream;
  7. import java.io.ObjectOutputStream;
  8. import java.io.Serializable;
  9.  
  10. public class Prototype implements Cloneable, Serializable {
  11.  
  12. private static final long serialVersionUID = 1L;
  13. private String string;
  14.  
  15. private SerializableObject obj;
  16.  
  17. /* 浅复制 */
  18. public Object clone() throws CloneNotSupportedException {
  19. Prototype proto = (Prototype) super.clone();
  20. return proto;
  21. }
  22.  
  23. /* 深复制 */
  24. public Object deepClone() throws IOException, ClassNotFoundException {
  25.  
  26. /* 写入当前对象的二进制流 */
  27. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  28. ObjectOutputStream oos = new ObjectOutputStream(bos);
  29. oos.writeObject(this);
  30.  
  31. /* 读出二进制流产生的新对象 */
  32. ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
  33. ObjectInputStream ois = new ObjectInputStream(bis);
  34. return ois.readObject();
  35. }
  36.  
  37. public String getString() {
  38. return string;
  39. }
  40.  
  41. public void setString(String string) {
  42. this.string = string;
  43. }
  44.  
  45. public SerializableObject getObj() {
  46. return obj;
  47. }
  48.  
  49. public void setObj(SerializableObject obj) {
  50. this.obj = obj;
  51. }
  52. }
  53.  
  54. class SerializableObject implements Serializable {
  55. private static final long serialVersionUID = 1L;
  56. }

MainTest.java

  1. package com.david.prototype;
  2.  
  3. import java.io.IOException;
  4.  
  5. public class MainTest {
  6.  
  7. public static void main(String[] args) {
  8. Prototype pt = new Prototype();
  9. pt.setString("Dawei");
  10. pt.setObj(new SerializableObject());
  11. System.out.println("pt = " + pt);
  12. System.out.println("pt.getString = " + pt.getString());
  13. System.out.println("pt.getObj = " + pt.getObj());
  14. System.out.println("=============================================");
  15. try {
  16. Prototype pt_clone = (Prototype) pt.deepClone();
  17. System.out.println("pt = " + pt_clone);
  18. System.out.println("pt.getString = " + pt_clone.getString());
  19. System.out.println("pt.getObj = " + pt_clone.getObj());
  20. } catch (IOException e) {
  21. e.printStackTrace();
  22. } catch (ClassNotFoundException e) {
  23. e.printStackTrace();
  24. }/* catch (CloneNotSupportedException e) {
  25. e.printStackTrace();
  26. }*/
  27. }
  28.  
  29. }

注意红色代码,我们可以更换方法,分别调用深、浅两种clone方法,打出的log如下:

浅克隆:

  1. pt = com.david.prototype.Prototype@3ce53108
  2. pt.getString = Dawei
  3. pt.getObj = com.david.prototype.SerializableObject@6af62373
  4. =============================================
  5. pt = com.david.prototype.Prototype@459189e1
  6. pt.getString = Dawei
  7. pt.getObj = com.david.prototype.SerializableObject@6af62373

看红色部分,打出来的对象hashcode是一样的。

深克隆:

  1. pt = com.david.prototype.Prototype@2e6e1408
  2. pt.getString = Dawei
  3. pt.getObj = com.david.prototype.SerializableObject@3ce53108
  4. =============================================
  5. pt = com.david.prototype.Prototype@7ecd2c3c
  6. pt.getString = Dawei
  7. pt.getObj = com.david.prototype.SerializableObject@5013582d

看红、绿色部分,显然不一样,这说明克隆前后的SerializableObject obj对象不是同一个对象。

Java设计模式系列1--原型模式(Prototype Method)的更多相关文章

  1. 设计模式系列之原型模式(Prototype Pattern)——对象的克隆

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  2. 《JAVA设计模式》之原型模式(Prototype)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式.通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办 ...

  3. Net设计模式实例之原型模式( Prototype Pattern)

    一.原型模式简介(Brief Introduction) 原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象. Specify the kin ...

  4. Java设计模式系列-抽象工厂模式

    原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755412.html 一.概述 抽象工厂模式是对工厂方法模式的再升级,但是二者面对的场景稍显差别. ...

  5. Java设计模式系列-工厂方法模式

    原创文章,转载请标注出处:<Java设计模式系列-工厂方法模式> 一.概述 工厂,就是生产产品的地方. 在Java设计模式中使用工厂的概念,那就是生成对象的地方了. 本来直接就能创建的对象 ...

  6. Java设计模式系列-装饰器模式

    原创文章,转载请标注出处:<Java设计模式系列-装饰器模式> 一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是 ...

  7. C#设计模式系列:原型模式(Prototype)

    1.原型模式简介 1.1>.定义 原型模式(Prototype)用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象. 1.2>.使用频率 中 1.3>.原型模式应用 首先 ...

  8. 深度分析:java设计模式中的原型模式,看完就没有说不懂的

    前言 原型模式(Prototype模式)是指:用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象 原型模式是一种创建型设计模式,允许一个对象再创建另外一个可定制的对象,无需知道如何创建的 ...

  9. Java设计模式5:原型模式

    原型模式 原型模式属于对象的创建模式,通过给出一个原型对象来指明所有创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象,这就是原型模式的用意. 原型模式结构 原型模式要求对象实现一个 ...

随机推荐

  1. servletFileUpload

    引用:http://bbs.csdn.net/topics/390290685?page=1 Java code? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  2. 自定义view imageviw

    新建一个类继承imageview package com.exaple.myselfview; import android.content.Context; import android.graph ...

  3. HTML随学随机

    1.2D坐标系由X轴个y轴构成.其中,笛卡尔坐标系是最常见的2D坐标系. 2.HTML5 canvas2D坐标系: (1)canvas坐标原点:左上角. (2)canvas的x与y轴方向: (I)x轴 ...

  4. s3c2440 移值新内核 linux-4.1.36

    arm-linuxgcc version 4.3.2 经过试验,最高可以编译到 linux-4.1.36 ,在高的版本会有错误 ,可能是 GCC 编译器版本较低造成. 解压比较麻烦还要装一个 xz x ...

  5. 在虚拟机发布网站,设置服务器外网访问ip端口号

    这是虚机上的发布网站的网站端口号 这一步要在实机设置 做完这一步,在外网就可以访问你刚刚发布的站点了

  6. python中的正则表达式(re模块)

    一.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配.正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎 ...

  7. 删除DSO Change Log表数据

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  8. centos7 中libgdiplus的安装

    yum -y install libtool* git clone git://github.com/mono/libgdiplus.git cd libgdiplus ./autogen.sh -- ...

  9. centos配置163源

    1.参考Centos镜像帮助 (1.1)备份原始repo shell> sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/Ce ...

  10. 关于js touch事件 的引用设置

    一开始做前端页面的时候,接触的也是js,但是随后便被简单高效的jquery吸引过去,并一直使用至今. 而js,则被我主观的认为底层技术而抛弃. 直到这几天工作需要,研究移动端页面的触屏滑动事件,搜索j ...