設計模式Java原型模式

原型模式基本介紹

  • 原型模式(prototype模式)是指:用原型實例指定創建對象的種類,並且通過拷貝這些原型,創建新的對象
  • 原型模式是一種創建型設計模式,允許一個對象在創建另外一個可定製的對象,無需知道如何創建的細節
  • 工作原理:通過原型傳給要發動創建的對象,這個要發動創建的對象通過請求原型對象拷貝他們來實現,即對象.clone()

原型模式實現方式

默認實現方式,淺拷貝

實現一個Cloneable接口,實現clone方法

  • 對於數據類型是基本數據類型(包含字符串)的成員變量,淺拷貝會直接進行值傳遞,也就是將該屬性值複製一份給新的對象
  • 對於數據類型是引用數據類型的成員變量,比如說成員變量是某個數組,某個類的對象,那麼淺拷貝會進行引用傳遞,也就是將該成員變量的引用地址(內存地址)複製給創建的新對象。所以實際上兩個對象的該成員變量都指向的是一個實例。在這種情況下,在一個對象中修改該成員變量會影響到另外一個成員變量。
/**
 * @author justLym
 * @version 1.0.0 2020/3/25 20:30
 **/
public class Student implements Cloneable {
    private Integer id;
    private String name;
    private Integer age;
    private Boolean gender;
    private Float score;
    private String address;

	@Override
    protected Object clone() throws CloneNotSupportedException {
        Student student =  (Student) super.clone();
        return student;
    }
}

深拷貝

  • 複製對象的所在基本數據類型(包括string類型)的成員變量值
  • 爲所有引用數據類型的成員變量申請存儲空間,並複製每個引用數據類型成員變量所引用的對象,知道該對象可達的所有對象。也就是說,對象進行深拷貝要對整個對象(包括對象引用類型)進行拷貝。

實現深拷貝的兩種方式

重寫clone方法實現深拷貝
/**
 * @author justLym
 * @version 1.0.0 2020/3/25 20:30
 **/
public class Student implements Cloneable {
    private Integer id;
    private String name;
    private Integer age;
    private Boolean gender;
    private Float score;
    private String address;
    
    private Student friend;
    
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Student student =  (Student) super.clone();

        student.friend = (Student) this.friend.clone();
        return student;
    }
通過對象序列化實現深拷貝
public class Student implements Cloneable, Serializable {
    private Integer id;
    private String name;
    private Integer age;
    private Boolean gender;
    private Float score;
    private String address;

    private Student friend;

	@Override
    protected Object clone() {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;

        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;

        Student student = null;

        try {
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);

            oos.writeObject(this);

            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);

            student = (Student) ois.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return student;
    }

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