JAVA設計模式之原型模式
概念
原型模式(prototype),就是克隆技術。
-以某對象爲原型,複製出新的對象,新對象
具有原型對象的特點。
-相對於new產生一個對象需要繁瑣的數據準備或訪問權限,原型模式效率高(直接clone,避免了重新執行構造過程步驟。)
實現:
-實現Cloneable接口和clone方法
-Prototype模式中實現起來最困難的地方就是內存複製操作,所幸Java中提供了clone()方法替代我們做了絕大部分事情。
淺克隆和深克隆
-淺克隆:被複制的對象所有變量都含有原來對象相同的值,而所有的對其它對象的引用都仍然指向原來的對象。
-深克隆:
1. 深克隆把引用的變量指向複製過來的新對象,而不是原來被引用的對象;
2. 深克隆讓已實現Cloneable接口的類中的屬性也實現Cloneable接口;
3. 基本數據類型自動實現深克隆;
4. 可以利用序列化和反序列化實現深克隆。
代碼
實現深克隆1:
public class Sheep implements Cloneable{
private String name;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date birthday;
public Sheep(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
// return obj;
// 深克隆增加代碼
Sheep s = (Sheep) obj;
// 對屬性實現Cloneable接口的進行clone
s.setBirthday((Date) birthday.clone());
return s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
實現深克隆2 序列化:
package com.xyw55.gof.protptype;
import com.alibaba.fastjson.annotation.JSONField;
import java.io.*;
import java.util.Date;
/**
* 實現Cloneable, Serializable接口
*/
public class Sheep implements Cloneable, Serializable{
private String name;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date birthday;
public Sheep(String name, Date birthday) {
this.name = name;
this.birthday = birthday;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
// return obj;
// 深克隆增加代碼
Sheep s = (Sheep) obj;
// 對屬性實現Cloneable接口的進行clone
s.setBirthday((Date) birthday.clone());
return s;
}
// 序列化實現深克隆
public Sheep deepClone() throws IOException, ClassNotFoundException {
//將對象寫到流裏
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
//從流裏讀出來
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return (Sheep) ois.readObject();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}