天天看點

GOF23設計模式之原型模式之實作

      
/**
 * Sheep類,測試原型模式之淺拷貝
 * 時間:2015年4月1日09:44:29
 */
package com.bjsxt.cn.prototype;      
import java.io.Serializable;
import java.util.Date;      
public class Sheep implements Cloneable, Serializable {
 private String name;
 private Date date;
 
 public Sheep() {      
 }      
 
 public Sheep(String name, Date date) {
  super();
  this.name = name;
  this.date = date;
 }      
 public String getName() {
  return name;
 }      
 public void setName(String name) {
  this.name = name;
 }      
 public Date getDate() {
  return date;
 }      
 public void setDate(Date date) {
  this.date = date;
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {//通過這個方法的兩行代碼實作淺克隆
  Object object = super.clone();
  return object;
 }
 
}      
/**
 * Sheep類,測試原型模式之淺拷貝
 * 時間:2015年4月1日09:44:29
 */
package com.bjsxt.cn.prototype;      
import java.util.Date;      
public class Sheep2 implements Cloneable {
 private String name;
 private Date date;
 
 public Sheep2() {      
 }      
 
 public Sheep2(String name, Date date) {
  super();
  this.name = name;
  this.date = date;
 }      
 public String getName() {
  return name;
 }      
 public void setName(String name) {
  this.name = name;
 }      
 public Date getDate() {
  return date;
 }      
 public void setDate(Date date) {
  this.date = date;
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
  Object object = super.clone();
  
  //通過增加的這幾行實作深複制
  Sheep2 sheep = (Sheep2) object;
  sheep.date = (Date) this.date.clone();
  return object;
 }
 
}
      
/**
 * 測試淺克隆
 * 時間:2015年4月1日09:48:21
 * 程式了解:該小程式測試了圓形模式淺克隆的相關問題。對比程式和運作結果,我們可以看出以下幾點:
 *   1, 在修改之後,确實實作了複制,并且s1和s2的作為對象,所指向的屬性值完全相同
 *   2, s1和s2作為局部變量,值并不一樣。并且根據列印的結果,它們都屬于Sheep類型
 *   3, s1和s2為Sheep對象,該類具有Date屬性,但是s1和s2的date屬性指向了同樣的記憶體空間。這可以通過
 *    我們修改了date的值以後,s1和s2的屬性date都跟着改變了。顯然,在某些情況下,這不符合我們的要求,因為
 *    s1和s2還有粘連。我們希望它們能彼此獨立。修改一個對象,與另一個對象無關。當然這就是淺拷貝的問題所在了
 *
 */
package com.bjsxt.cn.prototype;      
import java.util.Date;      
public class Client1 {
 public static void main(String[] args) throws CloneNotSupportedException {
  Date date = new Date(3234324435L);
  Sheep s1 = new Sheep("少莉", date);
  Sheep s2 = (Sheep) s1.clone();
  System.out.println("----------修改之前------------");
  System.out.println(s1.getClass());
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  
  System.out.println(s2.getClass());
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
  
  System.out.println("----------修改-----------");
  
  date.setTime(4323423423L);
  System.out.println("----------修改之後-------------");
  
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
 }
}
/*
 * ----------修改之前------------
 [email protected]
 少莉
 Sat Feb 07 18:25:24 CST 1970
 [email protected]
 少莉
 Sat Feb 07 18:25:24 CST 1970
 ----------修改-----------
 ----------修改之後-------------
 [email protected]
 少莉
 Fri Feb 20 08:57:03 CST 1970
 [email protected]
 少莉
 Fri Feb 20 08:57:03 CST 1970      
 * 
 * */
      
/**
 * 測試深拷貝
 * 時間:2015年4月1日09:48:21
 * 程式了解:該小程式測試了原型模式深克隆的相關問題。對比程式和運作結果,我們可以看出以下幾點:
 *   通過程式,我們可以看出,在Sheep2類中的clone方法中增加了幾行語句
 *    @Override
 protected Object clone() throws CloneNotSupportedException {
  Object object = super.clone();
  
  //通過增加的這幾行實作深複制
  Sheep2 sheep = (Sheep2) object;
  sheep.date = (Date) this.date.clone();
  return object;
 }
 
 就實作了深拷貝,這是通過我們對屬性也進行了深拷貝實作的。
 */
package com.bjsxt.cn.prototype;      
import java.util.Date;      
public class Client2 {
 public static void main(String[] args) throws CloneNotSupportedException {
  Date date = new Date(3234324435L);
  String name = new String("少莉");
  Sheep2 s1 = new Sheep2(name, date);
  Sheep2 s2 = (Sheep2) s1.clone();
  System.out.println("----------修改之前------------");
  
  System.out.println("s1-------------");
  System.out.println(s1.getClass());
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2.getClass());
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
  
  System.out.println("----------修改-----------");
  
  date.setTime(43234234238989L);
  s1.setName("周傑倫");
  System.out.println("----------修改之後-------------");
  System.out.println("s1-------------");
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
 }
}
/*
 ----------修改之前------------
s1-------------
class com.bjsxt.cn.prototype.Sheep2
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970      
s2-------------
class com.bjsxt.cn.prototype.Sheep2
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
----------修改-----------
----------修改之後-------------
s1-------------
[email protected]
周傑倫
Fri Jan 15 13:30:38 CST 3340      
s2-------------
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970      
 * 
 * */
      
/**
 * 測試使用序列化和反序列化實作深拷貝。
 * 時間:2015年4月1日10:27:57
 * 注意:記住序列化的過程。
 */
package com.bjsxt.cn.prototype;      
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;      
public class Client3 {
 public static void main(String[] args) throws IOException, ClassNotFoundException {
  Date date = new Date(3234324435L);
  Sheep s1 = new Sheep("少莉", date);
  
  //把這個對象寫入到記憶體中的數組。通過使用位元組數組輸出流baos擷取記憶體中的一塊記憶體
  //外加一個處理流,友善操作,多态的存在,是以必須使用ObjectOutputStream類來聲明。
  ByteArrayOutputStream baos = new ByteArrayOutputStream();
  ObjectOutputStream oos = new ObjectOutputStream(baos);
  oos.writeObject(s1);
  byte[] bytes = baos.toByteArray();
  
  ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
  ObjectInputStream ois = new ObjectInputStream(bais);
  Sheep s2 = (Sheep) ois.readObject();
  
  
 System.out.println("----------修改之前------------");
  
  System.out.println("s1-------------");
  System.out.println(s1.getClass());
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2.getClass());
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
  
  System.out.println("----------修改-----------");
  
  date.setTime(43234234238989L);
  s1.setName("周傑倫");
  System.out.println("----------修改之後-------------");
  System.out.println("s1-------------");
  System.out.println(s1);
  System.out.println(s1.getName());
  System.out.println(s1.getDate());
  System.out.println();
  
  System.out.println("s2-------------");
  System.out.println(s2);
  System.out.println(s2.getName());
  System.out.println(s2.getDate());
 }
}
/**
 *
 * ----------修改之前------------
s1-------------
class com.bjsxt.cn.prototype.Sheep
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970      
s2-------------
class com.bjsxt.cn.prototype.Sheep
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
----------修改-----------
----------修改之後-------------
s1-------------
[email protected]
周傑倫
Fri Jan 15 13:30:38 CST 3340      
s2-------------
[email protected]
少莉
Sat Feb 07 18:25:24 CST 1970
*/
      
/**
 * 測試new方法和clone方法的效率比較
 * 通過運作結果我們可以看出,clone極大的提高了建立對象的效率。
 * 
 */
package com.bjsxt.cn.prototype;      
import java.util.Date;      
public class Client4 {
 public static void testNew(int size) {
  long start = System.currentTimeMillis();
  
  for (int i=0; i<size; i++) {
   Laptop tempLaptop = new Laptop();
  }
  
  long end = System.currentTimeMillis();
  
  System.out.println("New耗時: " + (end-start));
  
 }
 
 public static void testClone(int size) throws CloneNotSupportedException {
  long start = System.currentTimeMillis();
  Laptop t = new Laptop();
  for (int i=0; i<size-1; i++) {
   Laptop temp = (Laptop) t.clone();
  }
  
  long end = System.currentTimeMillis();
  System.out.println("Clone耗時: " + (end-start));
  
 }
 public static void main(String[] args) throws CloneNotSupportedException {
  testNew(1000);
  testClone(1000);
 }
}      
class Laptop implements Cloneable{
 public Laptop() {
  try {
   Thread.sleep(10);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }
 
 @Override
 protected Object clone() throws CloneNotSupportedException {
    //通過增加的這幾行實作淺複制
   Object object = super.clone();
   return object;
  }
  
}      
/*
 * New耗時: 10550
 Clone耗時: 10
 * 
 */