Prototype Pattern 原型模式
阿新 • • 發佈:2020-06-27
原先的方式
Sheep sheep = new Sheep("tom", 1, "white");
Sheep sheep1 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
System.out.println(sheep1);
總是要重新初始化物件, 而不是動態地獲得物件執行時的狀態, 不夠靈活, 如果中途添加了屬性也要改程式碼才行。
改進 使用clone()方法, 但必須由被clone類實現Cloneable介面。 => Prototype Pattern
(淺拷貝)
public class Sheep implements Cloneable{ @Override protected Object clone(){ Sheep sheep = null; try{ sheep = (Sheep) super.clone(); // 預設是淺拷貝 }catch (CloneNotSupportedException e){ e.printStackTrace(); } return sheep; } }
// NewClient.java public class NewClient { public static void main(String[] args) { Sheep sheep = new Sheep("Tom", 1, "White"); sheep.friend = new Sheep("Jerry", 2, "Black"); // shadow copy Sheep sheep1 = (Sheep) sheep.clone(); System.out.println(sheep1); System.out.println(sheep.hashCode()); //1360875712 System.out.println(sheep1.hashCode()); //1625635731 System.out.println(sheep.friend.hashCode()); // 1580066828 System.out.println(sheep1.friend.hashCode()); //1580066828 } }
深拷貝 (方式一:重寫clone()方法 方式二:通過物件序列化)
public class DeepPrototype implements Serializable, Cloneable {
public String name;
public Goat goat;
public DeepPrototype() {
}
// let's do the deep copy
//method 1 : overwrite clone()
@Override
protected Object clone() {
DeepPrototype deepPrototype = null;
try {
deepPrototype =(DeepPrototype) super.clone();
deepPrototype.goat = (Goat)goat.clone();
}catch (CloneNotSupportedException e){
e.printStackTrace();
}
return deepPrototype;
}
}
深拷貝 (通過物件序列化 RECOMMENDED)
public Object serializableClone(){
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
// Serialize
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this); // 將當前物件以物件流的方式輸出
//Unserialize
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
DeepPrototype deepPrototype = (DeepPrototype) ois.readObject();
return deepPrototype;
}catch (Exception e){
e.printStackTrace();
}finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}