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对象不是同一个对象。

 

 

你可能感兴趣的:(prototype)