Java面向對象設計模式(五)——原型模式

原型模式(Prototype)

      原型模式雖然是創建型的模式,但是與工程模式沒有關係,從名字即可看出,該模式的思想就是將一個對象作爲原型,對其進行復制、克隆,產生一個和原對象類似的新對象。本小結會通過對象的複製,進行講解。在Java中,複製對象是通過clone()實現的,先創建一個原型類:

[java] view plain copy
  1. public class Prototype implements Cloneable {  
  2.   
  3.     public Object clone() throws CloneNotSupportedException {  
  4.         Prototype proto = (Prototype) super.clone();  
  5.         return proto;  
  6.     }  
  7. }  

很簡單,一個原型類,只需要實現Cloneable接口,覆寫clone方法,此處clone方法可以改成任意的名稱,因爲Cloneable接口是個空接口,你可以任意定義實現類的方法名,如cloneA或者cloneB,因爲此處的重點是super.clone()這句話,super.clone()調用的是Object的clone()方法,而在Object類中,clone()是native的,具體怎麼實現,我會在另一篇文章中,關於解讀Java中本地方法的調用,此處不再深究。在這兒,我將結合對象的淺複製和深複製來說一下,首先需要了解對象深、淺複製的概念:

淺複製:將一個對象複製後,基本數據類型的變量都會重新創建,而引用類型,指向的還是原對象所指向的。

深複製:將一個對象複製後,不論是基本數據類型還有引用類型,都是重新創建的。簡單來說,就是深複製進行了完全徹底的複製,而淺複製不徹底。

此處,寫一個深淺複製的例子:

[java] view plain copy
  1. public class Prototype implements Cloneable, Serializable {  
  2.   
  3.     private static final long serialVersionUID = 1L;  
  4.     private String string;  
  5.   
  6.     private SerializableObject obj;  
  7.   
  8.     /* 淺複製 */  
  9.     public Object clone() throws CloneNotSupportedException {  
  10.         Prototype proto = (Prototype) super.clone();  
  11.         return proto;  
  12.     }  
  13.   
  14.     /* 深複製 */  
  15.     public Object deepClone() throws IOException, ClassNotFoundException {  
  16.   
  17.         /* 寫入當前對象的二進制流 */  
  18.         ByteArrayOutputStream bos = new ByteArrayOutputStream();  
  19.         ObjectOutputStream oos = new ObjectOutputStream(bos);  
  20.         oos.writeObject(this);  
  21.   
  22.         /* 讀出二進制流產生的新對象 */  
  23.         ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());  
  24.         ObjectInputStream ois = new ObjectInputStream(bis);  
  25.         return ois.readObject();  
  26.     }  
  27.   
  28.     public String getString() {  
  29.         return string;  
  30.     }  
  31.   
  32.     public void setString(String string) {  
  33.         this.string = string;  
  34.     }  
  35.   
  36.     public SerializableObject getObj() {  
  37.         return obj;  
  38.     }  
  39.   
  40.     public void setObj(SerializableObject obj) {  
  41.         this.obj = obj;  
  42.     }  
  43.   
  44. }  
  45.   
  46. class SerializableObject implements Serializable {  
  47.     private static final long serialVersionUID = 1L;  
  48. }  

要實現深複製,需要採用流的形式讀入當前對象的二進制輸入,再寫出二進制數據對應的對象。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章