1. 程式人生 > 實用技巧 >Prototype Pattern 原型模式

Prototype Pattern 原型模式

原先的方式

  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;
    }