1. 程式人生 > 實用技巧 >Java23種設計模式之建立型模式「原型模式」

Java23種設計模式之建立型模式「原型模式」

原型模式

/**
 * 原型模式
 * <p>
 * 淺複製(淺克隆):將一個物件複製後,基本資料型別的變數都會重新建立,而引用型別,指向的還是原物件所指向的
 * 深複製(深克隆):不管是基本資料型別還是引用型別,都會重新建立。簡單來說:就是深複製進行了完全徹底的複製
 * <p>
 * 注:
 * 實現 Cloneable 介面,並覆蓋其clone方法,並且宣告為 public
 * 淺複製和深複製建議不要混合使用,一個類中某些引用使用的淺複製,某些引用使用了深複製
 * 這是一種非常差的設計,特別是在涉及到類的繼承,父類有幾個引用的情況就非常複雜
 * 建議深複製和淺複製分開實現
 * <p>
 * 說明:
 * 這裡在一個物件類裡面寫了兩個複製邏輯,只是為了方便檢視和學習
 *
 * @author Mr.Lim
 */
public class Prototype implements Cloneable, Serializable {
    private static final long serialVersionUID = -2911276289956526976L;

    /**
     * 姓名
     */
    public String name;

    /**
     * 年齡
     */
    public Integer age;

    /**
     * 學生資訊物件
     */
    public Student student;

    /**
     * 淺複製
     */
    @Override
    public Prototype clone() {
        Prototype prototype = null;
        try {
            prototype = (Prototype) super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return prototype;
    }

    /**
     * 深複製
     * <p>
     * 注:
     * 本物件和物件裡面引用的物件都要實現 java.io.Serializable 介面
     */
    public Prototype deepClone() {

        try {
            // 寫入當前物件的二進位制流
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream);
            oos.writeObject(this);

            // 讀取當前物件的二進位制流
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(byteArrayInputStream);
            return (Prototype) ois.readObject();

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Student getStudent() {
        return student;
    }

    public void setStudent(Student student) {
        this.student = student;
    }

}