[知识点]纵谈设计模式 05原型模式

[知识点]漫谈设计模式 05原型模式

---------chapter 5 原型模式----------
--> 5.1 概论
 # Prototype 不等于 java.lang.Cloneable接口。
 5.2 原型模式
 # 当创建这些对象(一般是大对象)非常耗时或者创建过程非常复杂,
 # OOP 语言提供了内存中对象的复制,Java语言提供了对象的浅拷贝;
  -> 浅拷贝: 复制一个对象时,如果它的一个属性是引用,则复制这个引用。
  -> 深拷贝: 为此属性创建一个新对象。
 #
[知识点]纵谈设计模式 05原型模式
 
 # {code}
  public class PackageInfo implements Cloneable {
   public PackageInfo clone() {
    try {
     return (PackageInfo) super.clone();
    } catch(CloneNotSuportedException e) {
     System.out.println("Clone not allow.");
     return null;
    }
   }
   
   public static PackageInfo clonePackageInfo (String userName) {
    PackageInfo prototype = loadPackageInfo(userName);
    prototype = prototype.clone();
    prototype.setId(null);
    return prototype;
   }
  }
 {code}
 # 如若想使用 java.object.clone() method.有如下限制:
  - 1. 必须实现java.lang.Cloneable interface.
  - 2. 返回的是Object对象,需要强制转换。
  - 3. 该方法是protected, 如果在外界使用需重写并change the status to public.
  - 4. 采用逐个字节的方式从复制内存数据,复制了属性引用,而属性指向的对象本身没有被复制。 -->浅拷贝。
 5.5 Deep copy
 # 如何实现深拷贝。
  - 1. 拷贝对象时,递归地调用属性对象的克隆方法。
  - 2. 如果类实现了java.io.Serializable接口把原型对象序列化,然后反序列化的得到的对象。
 {code} //深拷贝的第二种实现
  public class DeepCopyBean {
   private String objectField;//1 原始类型属性
   private int primitiveField;//1 对象属性
   public DeepCopyBean deepCopy () {
    try {
     ByteArrayOutputStream buf = new ByteArrayOutputStream();
     ObjectOutputStream o = new ObjectOutputStream();
     o.writeObject(this);//2 序列化自己到流中
     
     ObjectInputStram in = new ObjectInputStram(
      new ByteArrayInputStream (buf.toByteArray()));
      return (DeepCopyBean) in.readObject();//2 从流中反序列化。
    } catch(IoException e) {
     e.printStackTrace();
    } catch (ClassNotFoundException e) {
     e.printStackTrace();
    }
    return null;
   }
   // checking the logic.
   public static void main (String [] args) {
    DeepCopyBean originalBean = new DeepCopyBean(1,new String("123"));
    //new String("123"); 创建了2个String:一个在字符串池中(后者),一个在对象堆中(前者)。
    DeepCopyBean newBean = originalBean.deepCopy();
    log.debug(originalBean.getPrimitiveField() == newBean.getPrimitiveField());
    log.debug(originalBean.getObjectField() == newBean.getObjectField());
    log.debug(originalBean.getObjectField().equals(newBean.getObjectField()));
   }
  }
  
 {code}