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