定义:通过拷贝原型创建新的对象。
调用者不需要知道任何创建细节,不调用构造函数。属于创建型模式。
适用场景:
1,类初始化消耗资源太多。
2,new产生一个对象需要非常繁琐的过程(数据准备,访问权限等)
3,构造函数比较复杂
4,循环体中产生大量对象时。
如:
BeanUtils.copy();//默认浅克隆,可以设置为深克隆
JSON,parseObject()
Copy --Guava
分为深克隆和浅克隆两种模式。
package com.gupaoedu.vip.pattern.prototype.deep;
import java.io.Serializable;
/**
* Created by Tom.
*/
public class JinGuBang implements Serializable {
public float h = 100;
public float d = 10;
public void big(){
this.d *= 2;
this.h *= 2;
}
public void small(){
this.d /= 2;
this.h /= 2;
}
}
package com.gupaoedu.vip.pattern.prototype.deep;
import java.util.Date;
/**
* Created by Tom.
*/
public class Monkey {
public int height;
public int weight;
public Date birthday;
}
package com.gupaoedu.vip.pattern.prototype.deep;
import java.io.*;
import java.util.Date;
/**
* Created by Tom.
*/
public class QiTianDaSheng extends Monkey implements Cloneable,Serializable {
public JinGuBang jinGuBang;
public QiTianDaSheng(){
//只是初始化
this.birthday = new Date();
this.jinGuBang = new JinGuBang();
}
@Override
protected Object clone() throws CloneNotSupportedException {
return this.deepClone();
}
public Object deepClone(){
try{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
QiTianDaSheng copy = (QiTianDaSheng)ois.readObject();
copy.birthday = new Date();
return copy;
}catch (Exception e){
e.printStackTrace();
return null;
//关闭流等操作,忽略不写
}
}
public QiTianDaSheng shallowClone(QiTianDaSheng target){
QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
qiTianDaSheng.height = target.height;
qiTianDaSheng.weight = target.height;
qiTianDaSheng.jinGuBang = target.jinGuBang;
qiTianDaSheng.birthday = new Date();
return qiTianDaSheng;
}
}
package com.gupaoedu.vip.pattern.prototype.deep;
public class DeepCloneTest {
public static void main(String[] args) {
QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
try {
QiTianDaSheng clone = (QiTianDaSheng)qiTianDaSheng.clone();
System.out.println("深克隆:" + (qiTianDaSheng.jinGuBang == clone.jinGuBang));
} catch (Exception e) {
e.printStackTrace();
}
QiTianDaSheng q = new QiTianDaSheng();
QiTianDaSheng n = q.shallowClone(q);
System.out.println("浅克隆:" + (q.jinGuBang == n.jinGuBang));
}
}
spring中scope="prototype"表示该实例是从内存中复制而来
和scope="singleton"常一起用。
ArrayList<E>实现了Cloneable接口
ArryList.copyof()方法,是将list中的每个元素一个个迭代,都重新创建并且分配内存,实现深克隆。
原型模式的缺点:
必须配备克隆方法。
克隆复杂对象,或者对克隆出来的对象进行复杂改造时,容易产生风险。
深拷贝和浅拷贝要运用得当。