Java設計模式之-原型模式(prototype)
原型模式雖然是創建型的模式,但是與工程模式沒有關係,從名字即可看出,該模式的思想就是將一個對象作爲原型,對其進行復制、克隆,產生一個和原對象類似的新對象。本小結會通過對象的複製,進行講解。在Java中,複製對象是通過clone()實現的,先創建一個原型類:
public class Prototype implements Cloneable {
public Object clone() throws CloneNotSupportedException {
Prototype proto = (Prototype) super.clone();
return proto;
}
}
很簡單,一個原型類,只需要實現Cloneable接口,覆寫clone方法,此處clone方法可以改成任意的名稱,因爲Cloneable接口是個空接口,你可以任意定義實現類的方法名,如cloneA或者cloneB,因爲此處的重點是super.clone()這句話,super.clone()調用的是Object的clone()方法。在這兒,我將結合對象的淺複製和深複製來說一下,首先需要了解對象深、淺複製的概念:
淺複製:將一個對象複製後,基本數據類型的變量都會重新創建,而引用類型,指向的還是原對象所指向的。
深複製:將一個對象複製後,不論是基本數據類型還有引用類型,都是重新創建的。簡單來說,就是深複製進行了完全徹底的複製,而淺複製不徹底。
此處,寫一個深淺複製的例子:
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class DeepCloneTest {
public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {
// TODO Auto-generated method stub
DeepClone dandan=new DeepClone("dandan",1);
// 淺複製
DeepClone benben=(DeepClone) dandan.clone();
System.out.println(dandan.getName()==benben.getName());
System.out.println(dandan.getID()==benben.getID());
// 深複製
DeepClone yingwen=(DeepClone)dandan.deepClone();
System.out.println(dandan.getName()==yingwen.getName());
System.out.println(dandan.getID()==yingwen.getID());
}
}
class DeepClone implements Cloneable,Serializable
{
private static final long serialVersionUID = 1L;
private String name;
private int id;
public DeepClone(String name,int id){
this.name=name;
this.id=id;
}
public void setName(String newname){
name=newname;
}
public String getName(){
return name;
}
public int getID(){
return id;
}
// 淺複製
public Object clone() throws CloneNotSupportedException{
DeepClone shallow=(DeepClone) super.clone();
return shallow;
}
// 深複製,要藉助流,
public Object deepClone() throws IOException, ClassNotFoundException{
// 寫入當前對象的二進制流
ByteArrayOutputStream bos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.writeObject(this);
// 讀出二進制流產生的新對象
ByteArrayInputStream bis=new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois=new ObjectInputStream(bis);
DeepClone deep=(DeepClone) ois.readObject();
return deep;
}
}
輸出結果:
true
true
false
true
輸出結果驗證了前面關於深淺複製的定義。
要實現深複製,需要採用流的形式讀入當前對象的二進制輸入,再寫出二進制數據對應的對象。