zoukankan      html  css  js  c++  java
  • Java设计模式系列1--原型模式(Prototype Method)

    2014-02-14 11:27:33 

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

    原型模式,从名字即可看出,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。在Java中,复制对象是通过clone()实现的,调用的是Objectclone()方法,而在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如下:

    浅克隆:

    pt = com.david.prototype.Prototype@3ce53108
    pt.getString = Dawei
    pt.getObj = com.david.prototype.SerializableObject@6af62373
    =============================================
    pt = com.david.prototype.Prototype@459189e1
    pt.getString = Dawei
    pt.getObj = com.david.prototype.SerializableObject@6af62373

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

    深克隆:

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

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

  • 相关阅读:
    函数依赖(转)
    C++对象的深拷贝和浅拷贝
    C++临时匿名对象
    C++操作符重载
    C数组和指针
    动态开发入门之Servlet
    数据库的CURD操作 以及经典的sql语句
    如何删除07版word页眉页脚的横线
    数据库的连接查询
    经典面试题 详细解析Java中抽象类和接口的区别
  • 原文地址:https://www.cnblogs.com/wlrhnh/p/3549318.html
Copyright © 2011-2022 走看看