【GOF23設計模式】原型模式
來源:http://www.bjsxt.com/?
一、【GOF23設計模式】_原型模式、prototype、淺復制、深復制、Cloneable接口?
淺復制
1 package com.test.prototype; 2 3 import java.util.Date; 4 5 /** 6 * 淺復制 7 */ 8 public class Sheep implements Cloneable{//Cloneable為標記接口 9 private String sname; 10 private Date birthday; 11 12 @Override 13 protected Object clone() throws CloneNotSupportedException { 14 Object obj = super.clone();//直接調用object對象的clone()方法 15 return obj; 16 } 17 18 public Sheep() { 19 } 20 21 public Sheep(String sname, Date birthday) { 22 super(); 23 this.sname = sname; 24 this.birthday = birthday; 25 } 26 27 public String getSname() { 28 return sname; 29 } 30 31 public void setSname(String sname) { 32 this.sname = sname; 33 } 34 35 public Date getBirthday() { 36 return birthday; 37 } 38 39 public void setBirthday(Date birthday) { 40 this.birthday = birthday; 41 } 42 }
1 package com.test.prototype; 2 3 import java.util.Date; 4 /** 5 * 測試原型模式(淺復制) 6 */ 7 public class Client { 8 public static void main(String[] args) throws Exception { 9 Date date = new Date(3333332323L); 10 Sheep s1 = new Sheep("少利", date); 11 Sheep s2 = (Sheep) s1.clone(); 12 13 System.out.println(s1); 14 System.out.println(s1.getSname()); 15 System.out.println(s1.getBirthday()); 16 date.setTime(332324355555555L);//淺復制:s1和s2指向同一date對象的地址,一改全改 17 System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday() 18 19 s2.setSname("多利"); 20 System.out.println(s2); 21 System.out.println(s2.getSname()); 22 System.out.println(s2.getBirthday()); 23 } 24 }
控制臺輸出:s1修改時間后,s2的也跟著改(Fri Dec 10 00:59:15 CST 12500)
com.test.prototype.Sheep@1db9742 少利 Sun Feb 08 21:55:32 CST 1970 Fri Dec 10 00:59:15 CST 12500 com.test.prototype.Sheep@647e05 多利 Fri Dec 10 00:59:15 CST 12500
深復制
1 package com.test.prototype; 2 3 import java.util.Date; 4 5 /** 6 * 深復制 7 */ 8 public class Sheep2 implements Cloneable{//Cloneable為標記接口 9 private String sname; 10 private Date birthday; 11 12 @Override 13 protected Object clone() throws CloneNotSupportedException { 14 Object obj = super.clone();//直接調用object對象的clone()方法 15 16 //添加如下代碼實現深復制(Deep Clone) 17 Sheep2 s = (Sheep2) obj; 18 s.birthday = (Date) this.birthday.clone();//屬性克隆! 19 20 return obj; 21 } 22 23 public Sheep2() { 24 } 25 26 public Sheep2(String sname, Date birthday) { 27 super(); 28 this.sname = sname; 29 this.birthday = birthday; 30 } 31 32 public String getSname() { 33 return sname; 34 } 35 36 public void setSname(String sname) { 37 this.sname = sname; 38 } 39 40 public Date getBirthday() { 41 return birthday; 42 } 43 44 public void setBirthday(Date birthday) { 45 this.birthday = birthday; 46 } 47 }
1 package com.test.prototype; 2 3 import java.util.Date; 4 /** 5 * 測試原型模式(深復制) 6 */ 7 public class Client2 { 8 public static void main(String[] args) throws Exception { 9 Date date = new Date(3333332323L); 10 Sheep2 s1 = new Sheep2("少利", date); 11 Sheep2 s2 = (Sheep2) s1.clone(); 12 13 System.out.println(s1); 14 System.out.println(s1.getSname()); 15 System.out.println(s1.getBirthday()); 16 date.setTime(332324355555555L);//淺復制:s1和s2指向同一date對象的地址,一改全改 17 System.out.println(s1.getBirthday());//s1.getBirthday() == s2.getBirthday() 18 19 s2.setSname("多利"); 20 System.out.println(s2); 21 System.out.println(s2.getSname()); 22 System.out.println(s2.getBirthday()); 23 } 24 }
控制臺輸出:s1修改時間后,s2還是最初的(Sun Feb 08 21:55:32 CST 1970)
com.test.prototype.Sheep2@1db9742 少利 Sun Feb 08 21:55:32 CST 1970 Fri Dec 10 00:59:15 CST 12500 com.test.prototype.Sheep2@647e05 多利 Sun Feb 08 21:55:32 CST 1970
二、【GOF23設計模式】_原型模式、反序列化實現深復制、效率對比、創建型模式總結?
利用序列化和反序列化技術實現深復制
1 package com.test.prototype; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.ByteArrayOutputStream; 5 import java.io.ObjectInputStream; 6 import java.io.ObjectOutputStream; 7 import java.util.Date; 8 /** 9 * 原型模式(使用序列化和反序列化的方式實現深復制) 10 */ 11 public class Client3 { 12 public static void main(String[] args) throws Exception { 13 Date date = new Date(3333332323L); 14 Sheep s1 = new Sheep("少利", date); 15 16 System.out.println(s1); 17 System.out.println(s1.getSname()); 18 System.out.println(s1.getBirthday()); 19 20 // Sheep s2 = (Sheep) s1.clone(); 21 //使用序列化和反序列化實現深復制 22 //序列化 23 ByteArrayOutputStream bos = new ByteArrayOutputStream(); 24 ObjectOutputStream oos = new ObjectOutputStream(bos); 25 oos.writeObject(s1); 26 byte[] bytes = bos.toByteArray(); 27 28 //反序列化 29 ByteArrayInputStream bis = new ByteArrayInputStream(bytes); 30 ObjectInputStream ois = new ObjectInputStream(bis); 31 32 Sheep s2 = (Sheep) ois.readObject();//深復制的對象 33 34 System.out.println("修改原型對象的屬性值"); 35 date.setTime(332324355555555L); 36 System.out.println(s1.getBirthday()); 37 38 s2.setSname("多利"); 39 System.out.println(s2); 40 System.out.println(s2.getSname()); 41 System.out.println(s2.getBirthday()); 42 } 43 }
短時間大量創建對象時,原型模式和普通new方式效率測試:
1 package com.test.prototype; 2 /** 3 * 測試普通new方式創建對象和clone方式創建對象的效率差異! 4 * 如果需要短時間創建大量對象,并且new的過程比較耗時,則可以考慮使用原型模式! 5 */ 6 public class Client4 { 7 8 public static void testNew(int size){ 9 long start = System.currentTimeMillis(); 10 for (int i = 0; i < size; i++) { 11 Laptop t = new Laptop(); 12 } 13 long end = System.currentTimeMillis(); 14 System.out.println("new的方式創建耗時:" + (end - start)); 15 } 16 17 public static void testClone(int size) throws CloneNotSupportedException{ 18 long start = System.currentTimeMillis(); 19 Laptop t = new Laptop(); 20 for (int i = 0; i < size; i++) { 21 Laptop temp = (Laptop) t.clone(); 22 } 23 long end = System.currentTimeMillis(); 24 System.out.println("clone的方式創建耗時:" + (end - start)); 25 } 26 27 public static void main(String[] args) throws Exception { 28 testNew(1000); 29 testClone(1000); 30 } 31 } 32 33 class Laptop implements Cloneable{//筆記本電腦 34 public Laptop(){ 35 try{ 36 Thread.sleep(10);//模擬創建對象耗時的過程! 37 }catch(InterruptedException e){ 38 e.printStackTrace(); 39 } 40 } 41 42 @Override 43 protected Object clone() throws CloneNotSupportedException { 44 Object obj = super.clone();//直接調用object對象的clone()方法 45 return obj; 46 } 47 }
控制臺輸出:
new的方式創建耗時:10168
clone的方式創建耗時:10
開發中的應用場景:?
原型模式很少單獨出現,一般和工廠模式一起出現,通過clone的方法創建一個對象,然后由工廠方法提供給調用者。?
spring中bean的創建實際就是兩種:單例模式和原型模式(原型模式需要和工廠模式搭配起來)。
創建型模式的總結:?
posted on 2016-08-24 12:30 ErBing 閱讀(...) 評論(...) 編輯 收藏