又是一个辛苦的周一,好像每个周一都很累,我们戏称为周一综合证。
好不容易熬到下班,开心的回家准备开始愉快的王者峡谷之旅的时候,一个电话把我拉回了电脑旁边。"小胡,快看看,邮件怎么全发给一个客户了”。
打开代码,没错了,准备实例,clone发送。好像没问题呀。不信邪的我打印了日志,真的是clone引起的阿,吃一堑,长一智,赶紧恶补一下基础,翻出了clone准备好好研究一下。于是有了原型模式的学习。
Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式的核心就是一个clone方法。
package com.kaisen.mainland.Text;
import lombok.extern.slf4j.Slf4j;
/**
* @author huzhibo
* @Description:
* @date 2020/8/23 22:47
*/
@Slf4j
public class Demo implements Cloneable{
@Override
public Demo clone(){
Demo demo = null;
try{
demo = (Demo)super.clone();
}catch (Exception e){
log.info("克隆异常");
}
return demo;
}
}
好了,其实这块已经基本结束了,但是为什么会导致邮件业务出现异常呢,这块我们就要讲一下什么叫深拷贝,什么叫浅拷贝。废话不多说,直接上实例。
package com.kaisen.mainland.Text;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
/**
* @author huzhibo
* @Description:
* @date 2020/8/23 22:47
*/
@Slf4j
public class Demo implements Cloneable{
private ArrayList<String> arrayList = new ArrayList<>();
@Override
public Demo clone(){
Demo demo = null;
try{
demo = (Demo)super.clone();
}catch (Exception e){
log.info("克隆异常");
}
return demo;
}
public void setValue(String string){
this.arrayList.add(string);
}
public ArrayList<String> getArrayList(){
return arrayList;
}
}
package com.kaisen.mainland.Text;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
/**
* @author huzhibo
* @Description:
* @date 2020/8/23 22:47
*/
@Slf4j
public class Demo1 implements Cloneable{
private ArrayList<String> arrayList = new ArrayList<>();
@Override
public Demo1 clone(){
Demo1 demo = null;
try{
demo = (Demo1)super.clone();
this.arrayList = (ArrayList<String>) this.arrayList.clone();
}catch (Exception e){
log.info("克隆异常");
}
return demo;
}
public void setValue(String string){
this.arrayList.add(string);
}
public ArrayList<String> getArrayList(){
return arrayList;
}
}
好了,运行一下cline
package com.kaisen.mainland.Text;
/**
* @author huzhibo
* @Description: 场景类
* @date 2020/9/6 17:14
*/
public class Client {
public static void main(String[] args) {
Demo demo = new Demo();
demo.setValue("张三");
Demo demoClone = demo.clone();
demoClone.setValue("胡旺旺");
System.out.println("浅拷贝结果原对象为:"+demo.toString());
Demo1 demo1 = new Demo1();
demo1.setValue("张三");
Demo1 demo1Clone = demo1.clone();
demo1Clone.setValue("胡旺旺");
System.out.println("深拷贝结果原对象为:"+demo1.toString());
}
}
结果输出如下:
浅拷贝结果原对象为:Demo(arrayList=[张三, 胡旺旺])
深拷贝结果原对象为:Demo1(arrayList=[张三])
观察一下两个demo和demo1的区别,其实只有下面一句话:
this.arrayList = (ArrayList<String>) this.arrayList.clone();
也就是说,object提供的clone只是拷贝了对象本身,背心内部的数组,对象都不会拷贝。如果我们场景中拷贝的对象和原始对象对应的不是一个值,那我们就需要对该对象中的所有的数组,对象进行深度拷贝。
好了,到此邮件的问题已经解决了,处理了,我深度拷贝一下接收人就可以了,那明天挨骂的事情明天再说呗。
clone还有一个特性,就是构造方法不会被执行。
那说了这么多,原型模式有什么优缺点点,我们分析一下:
原型模式使用的clone是二进制的拷贝,比new性能好很多,如果一个对象会被频繁修改使用,我们可以考虑clone。
原型模式还有一个特点就是套别构造函数的约束。