原型模式(Prototype Pattern)(如何让快速构建对象的方法总结):
1、原型实例指定创建对象得种类,并且通过拷贝这些原型创建新的对象。
2、调用者不需要知道创建细节,不调用构造方法
3、属于创建型模式
一、使用场景:
1、类初始化资源较多
2、new产生得对象需要非常繁琐得过程(数据准备、访问权限、、)
3、构造函数比较复杂
4、循环体中生产大量对象时
可以使用以下方法进行直接赋值例如(原型模式):
- BeanUtils.copy()
- JSON.parseObject()
- Guava(Copy工具类)
二、浅克隆
1、定义一个猴子对象
package com.ckw.pattern.prototype;
import java.util.Date;
/**
* @author ckw
* @version 1.0
* @date 2020/6/8 20:38
* @description: 猴子
*/
public class Monkey {
public int height;
public int weight;
public Date birthday;
}
2、定义一个金箍棒对象
package com.ckw.pattern.prototype;
import java.io.Serializable;
/**
* @author ckw
* @version 1.0
* @date 2020/6/8 20:39
* @description: 金箍棒
*/
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;
}
}
3、定义齐天大圣对象,进行深克隆(每个齐天大圣拥有不同得金箍棒)与浅克隆(每个齐天大圣拥有同一个金箍棒)
package com.ckw.pattern.prototype;
import java.io.*;
import java.util.Date;
/**
* @author ckw
* @version 1.0
* @date 2020/6/8 20:39
* @description: 齐天大圣
*/
public class QiTianDaSheng extends Monkey implements Cloneable, Serializable {
public JinGuBang jinGuBang;
public QiTianDaSheng(JinGuBang jinGuBang) {
this.birthday = new Date();
this.jinGuBang = jinGuBang;
}
public QiTianDaSheng() {
}
@Override
protected Object clone() throws CloneNotSupportedException {
return this.deepClone();
}
//深度克隆
private QiTianDaSheng deepClone() {
try {
//进行序列化反序列化创建对象
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(this);
ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream);
QiTianDaSheng copy = (QiTianDaSheng)objectInputStream.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;
}
}
4、进行克隆测试
package com.ckw.pattern.prototype;
/**
* @author ckw
* @version 1.0
* @date 2020/6/8 20:49
* @description: 深克隆与浅克隆区别:
* 浅克隆:如果原对象中得属性有引用数据类型,则只是把引用类型得地址值赋值给了克隆后得对象
* 相当于原对象与克隆后得对象中引用类型属性是指向同一个地址值得
* 深克隆:与浅克隆相反,引用类型属性都是重新创建得
*/
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
QiTianDaSheng qiTianDaSheng = new QiTianDaSheng();
qiTianDaSheng.jinGuBang = new JinGuBang();
QiTianDaSheng deepCopy = (QiTianDaSheng)qiTianDaSheng.clone();
System.out.println("深度克隆后得金箍棒------》"+deepCopy.jinGuBang);
System.out.println("深度克隆原来得金箍棒------》"+qiTianDaSheng.jinGuBang);
QiTianDaSheng shallowCopy = qiTianDaSheng.shallowClone(qiTianDaSheng);
System.out.println("浅克隆后得金箍棒------》"+shallowCopy.jinGuBang);
System.out.println("浅克隆原来得金箍棒------》"+qiTianDaSheng.jinGuBang);
}
}