深克隆与浅克隆
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
package top.fjy8018.designpattern.pattern.creational.prototype.clone;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 原型模式:使用原型实例指定待创建对象的类型,并且通过<strong>复制</strong>这个原型来创建新的对象
|
||||
* 适用于初始化对象复杂的场景
|
||||
* <p>
|
||||
* 邮件——深克隆实现
|
||||
*
|
||||
* @author F嘉阳
|
||||
* @date 2018-09-25 20:39
|
||||
*/
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
public class CMailAfter implements Cloneable {
|
||||
|
||||
private String name;
|
||||
/**
|
||||
* String类型本身是不可变,不需要重新实现深克隆
|
||||
*/
|
||||
private Date date;
|
||||
private String content;
|
||||
|
||||
public CMailAfter() throws InterruptedException {
|
||||
// 模拟调用构造器需要复杂过程
|
||||
Thread.sleep(100);
|
||||
log.debug(this.getClass().getSimpleName() + "构造器调用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 带上父类toString方法查看是否为同一个对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CMailAfter{" +
|
||||
"name='" + name + '\'' +
|
||||
", date=" + date +
|
||||
", content='" + content + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用克隆函数不需要调用构造器以此加快实例化速度
|
||||
* 通过调用每个属性的克隆方法实现深克隆
|
||||
*
|
||||
* @return
|
||||
* @throws CloneNotSupportedException
|
||||
*/
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
CMailAfter mail = (CMailAfter) super.clone();
|
||||
// 单独对Date进行克隆
|
||||
mail.date = (Date) date.clone();
|
||||
return mail;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package top.fjy8018.designpattern.pattern.creational.prototype.clone;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 原型模式:使用原型实例指定待创建对象的类型,并且通过<strong>复制</strong>这个原型来创建新的对象
|
||||
* 适用于初始化对象复杂的场景
|
||||
* <p>
|
||||
* 邮件
|
||||
*
|
||||
* @author F嘉阳
|
||||
* @date 2018-09-25 20:39
|
||||
*/
|
||||
@Slf4j
|
||||
@Getter
|
||||
@Setter
|
||||
public class CMailBefore implements Cloneable {
|
||||
|
||||
private String name;
|
||||
private Date date;
|
||||
private String content;
|
||||
|
||||
public CMailBefore() throws InterruptedException {
|
||||
// 模拟调用构造器需要复杂过程
|
||||
Thread.sleep(100);
|
||||
log.debug(this.getClass().getSimpleName() + "构造器调用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 带上父类toString方法查看是否为同一个对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CMailBefore{" +
|
||||
"name='" + name + '\'' +
|
||||
", date=" + date +
|
||||
", content='" + content + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用克隆函数不需要调用构造器以此加快实例化速度
|
||||
* 通过调用每个属性的克隆方法实现深克隆
|
||||
*
|
||||
* @return
|
||||
* @throws CloneNotSupportedException
|
||||
*/
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
return super.clone();
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,10 @@ import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import top.fjy8018.designpattern.pattern.creational.prototype.after.AMail;
|
||||
import top.fjy8018.designpattern.pattern.creational.prototype.after.AMailUtil;
|
||||
import top.fjy8018.designpattern.pattern.creational.prototype.clone.CMailAfter;
|
||||
import top.fjy8018.designpattern.pattern.creational.prototype.clone.CMailBefore;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Slf4j
|
||||
class BMailTest {
|
||||
@@ -66,6 +70,73 @@ class BMailTest {
|
||||
}
|
||||
// 本意希望在发送完所有邮件后保存开始的正文
|
||||
AMailUtil.saveOriginMail(mail);
|
||||
}
|
||||
|
||||
/**
|
||||
* 由于String不可变性保证其稳定性,而Date没有单独进行属性克隆导致
|
||||
* <p>
|
||||
* output
|
||||
* ===
|
||||
* CMailBefore构造器调用
|
||||
* 15d0c81b CMailBefore{name='原始', date=Thu Jan 01 08:00:00 CST 1970, content='原始正文'}
|
||||
* 4b1c1ea0 CMailBefore{name='原始', date=Thu Jan 01 08:00:00 CST 1970, content='原始正文'}
|
||||
* ===============
|
||||
* 15d0c81b CMailBefore{name='更新', date=Sun Sep 09 09:46:39 CST 2001, content='原始正文'}
|
||||
* 4b1c1ea0 CMailBefore{name='原始', date=Sun Sep 09 09:46:39 CST 2001, content='原始正文'}
|
||||
* 耗时109ms
|
||||
* ===
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
void cloneTestBefore() throws Exception {
|
||||
CMailBefore mail1 = new CMailBefore();
|
||||
mail1.setName("原始");
|
||||
mail1.setContent("原始正文");
|
||||
mail1.setDate(new Date(0L));
|
||||
CMailBefore mail2 = (CMailBefore) mail1.clone();
|
||||
log.debug(Integer.toHexString(mail1.hashCode()) + " " + mail1);
|
||||
log.debug(Integer.toHexString(mail2.hashCode()) + " " + mail2);
|
||||
|
||||
// 改变属性值
|
||||
mail1.setName("更新");
|
||||
mail1.getDate().setTime(999999999999L);
|
||||
// 注意,若使用mail1.setDate(new Date());方式赋值不会导致两者同时变更
|
||||
log.debug("===============");
|
||||
log.debug(Integer.toHexString(mail1.hashCode()) + " " + mail1);
|
||||
log.debug(Integer.toHexString(mail2.hashCode()) + " " + mail2);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* output
|
||||
* ===
|
||||
* CMailAfter构造器调用
|
||||
* 15d0c81b CMailAfter{name='原始', date=Thu Jan 01 08:00:00 CST 1970, content='原始正文'}
|
||||
* 4b1c1ea0 CMailAfter{name='原始', date=Thu Jan 01 08:00:00 CST 1970, content='原始正文'}
|
||||
* ===============
|
||||
* 15d0c81b CMailAfter{name='更新', date=Sun Sep 09 09:46:39 CST 2001, content='原始正文'}
|
||||
* 4b1c1ea0 CMailAfter{name='原始', date=Thu Jan 01 08:00:00 CST 1970, content='原始正文'}
|
||||
* 耗时110ms
|
||||
* ===
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
void cloneTestAfter() throws Exception {
|
||||
CMailAfter mail1 = new CMailAfter();
|
||||
mail1.setName("原始");
|
||||
mail1.setContent("原始正文");
|
||||
mail1.setDate(new Date(0L));
|
||||
CMailAfter mail2 = (CMailAfter) mail1.clone();
|
||||
log.debug(Integer.toHexString(mail1.hashCode()) + " " + mail1);
|
||||
log.debug(Integer.toHexString(mail2.hashCode()) + " " + mail2);
|
||||
|
||||
// 改变属性值
|
||||
mail1.setName("更新");
|
||||
mail1.getDate().setTime(999999999999L);
|
||||
log.debug("===============");
|
||||
log.debug(Integer.toHexString(mail1.hashCode()) + " " + mail1);
|
||||
log.debug(Integer.toHexString(mail2.hashCode()) + " " + mail2);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user