原型模式基本介紹
- 原型模式(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;
}