2.原型模式
@Data
public class PrototypeSheep implements Cloneable{
private String name;
private Integer age;
private String color;
private PrototypeSheep friend;
public PrototypeSheep() {
}
public PrototypeSheep(String name, Integer age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
@Override
public String toString() {
return "PrototypeSheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
", friend=" + friend +
'}';
}
/**
* 克隆该实例,采用默认的clone方法来完成
* @return
*/
@Override
protected Object clone() {
PrototypeSheep sheep = null;
try {
sheep = (PrototypeSheep) super.clone();
} catch (Exception e) {
e.printStackTrace();
}
return sheep;
}
}x
1
2
public class PrototypeSheep implements Cloneable{3
4
private String name;5
private Integer age;6
private String color;7
8
private PrototypeSheep friend;9
public PrototypeSheep() {10
}11
12
public PrototypeSheep(String name, Integer age, String color) {13
this.name = name;14
this.age = age;15
this.color = color;16
}17
18
19
20
public String toString() {21
return "PrototypeSheep{" +22
"name='" + name + '\'' +23
", age=" + age +24
", color='" + color + '\'' +25
", friend=" + friend +26
'}';27
}28
29
/**30
* 克隆该实例,采用默认的clone方法来完成31
* @return32
*/33
34
protected Object clone() {35
PrototypeSheep sheep = null;36
37
try {38
sheep = (PrototypeSheep) super.clone();39
} catch (Exception e) {40
e.printStackTrace();41
}42
return sheep;43
}44
}测试
public class client {
public static void main(String[] args) {
PrototypeSheep sheep = new PrototypeSheep("tom", 1, "白色");
PrototypeSheep friend = new PrototypeSheep("jack", 2, "黑色");
sheep.setFriend(friend);
PrototypeSheep sheep1 = (PrototypeSheep) sheep.clone();
PrototypeSheep sheep2 = (PrototypeSheep) sheep.clone();
PrototypeSheep sheep3 = (PrototypeSheep) sheep.clone();
sheep1.getFriend().setColor("蓝色");
System.out.println("sheep = " + sheep +" sheep.friend="+ sheep.getFriend().hashCode());
System.out.println("sheep1 = " + sheep1 +" sheep1.friend="+ sheep1.getFriend().hashCode());
System.out.println("sheep2 = " + sheep2 +" sheep2.friend="+ sheep2.getFriend().hashCode());
System.out.println("sheep3 = " + sheep3 +" sheep3.friend="+ sheep3.getFriend().hashCode());
}
}18
1
public class client {2
public static void main(String[] args) {3
PrototypeSheep sheep = new PrototypeSheep("tom", 1, "白色");4
PrototypeSheep friend = new PrototypeSheep("jack", 2, "黑色");5
sheep.setFriend(friend);6
7
PrototypeSheep sheep1 = (PrototypeSheep) sheep.clone();8
PrototypeSheep sheep2 = (PrototypeSheep) sheep.clone();9
PrototypeSheep sheep3 = (PrototypeSheep) sheep.clone();10
sheep1.getFriend().setColor("蓝色");11
12
System.out.println("sheep = " + sheep +" sheep.friend="+ sheep.getFriend().hashCode());13
System.out.println("sheep1 = " + sheep1 +" sheep1.friend="+ sheep1.getFriend().hashCode());14
System.out.println("sheep2 = " + sheep2 +" sheep2.friend="+ sheep2.getFriend().hashCode());15
System.out.println("sheep3 = " + sheep3 +" sheep3.friend="+ sheep3.getFriend().hashCode());16
17
}18
}
对于默认实现的原型,对于引用类型的属性,克隆的对象依然保持的是原对象的指针的指向
每个克隆出的对象的其引用属性地址的hashCode是一样的
于是就引出了深克隆(深拷贝)


public class DeepCloneableTarget implements Serializable,Cloneable {
private static final long serialVersionUID = -5967898240709529077L;
private String cloneName;
private String cloneClass;
public DeepCloneableTarget() {
}
public DeepCloneableTarget(String cloneName, String cloneClass) {
this.cloneName = cloneName;
this.cloneClass = cloneClass;
}
public String getCloneName() {
return cloneName;
}
public void setCloneName(String cloneName) {
this.cloneName = cloneName;
}
public String getCloneClass() {
return cloneClass;
}
public void setCloneClass(String cloneClass) {
this.cloneClass = cloneClass;
}
/**
* 该类的属性,都是String,因此使用默认的clone完成即可
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}42
1
public class DeepCloneableTarget implements Serializable,Cloneable {2
private static final long serialVersionUID = -5967898240709529077L;3
4
private String cloneName;5
private String cloneClass;6
7
8
public DeepCloneableTarget() {9
}10
11
public DeepCloneableTarget(String cloneName, String cloneClass) {12
this.cloneName = cloneName;13
this.cloneClass = cloneClass;14
}15
16
public String getCloneName() {17
return cloneName;18
}19
20
public void setCloneName(String cloneName) {21
this.cloneName = cloneName;22
}23
24
public String getCloneClass() {25
return cloneClass;26
}27
28
public void setCloneClass(String cloneClass) {29
this.cloneClass = cloneClass;30
}31
32
33
/**34
* 该类的属性,都是String,因此使用默认的clone完成即可35
* @return36
* @throws CloneNotSupportedException37
*/38
39
protected Object clone() throws CloneNotSupportedException {40
return super.clone();41
}42
}package cn.xxm.gof23.creational.prototype.deepclone;
import java.io.*;
/**
* @program: gof23
* @link: 55864455@qq.com
* @author: Mr.Xxm
* @create: 2020-02-15 14:46
**/
public class DeepProtoType implements Serializable,Cloneable {
private static final long serialVersionUID = 5180880872263164878L;
private String name;
private DeepCloneableTarget deepCloneableTarget; // 引用类型
public DeepProtoType() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public DeepCloneableTarget getDeepCloneableTarget() {
return deepCloneableTarget;
}
public void setDeepCloneableTarget(DeepCloneableTarget deepCloneableTarget) {
this.deepCloneableTarget = deepCloneableTarget;
}
@Override
public String toString() {
return "DeepProtoType{" +
"name='" + name + '\'' +
", deepCloneableTarget=" + deepCloneableTarget +
'}';
}
/**
* 深拷贝-方式1 使用clone方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
Object deep = null;
// 这里完成对基本数据类型(属性)和String的克隆
deep = super.clone();
// 对引用类型的属性,进行单独处理
DeepProtoType deepProtoType = (DeepProtoType) deep;
DeepCloneableTarget deepCloneableTarget = (DeepCloneableTarget) deepProtoType.getDeepCloneableTarget().clone();
deepProtoType.setDeepCloneableTarget(deepCloneableTarget);
return deep;
}
// 深拷贝 - 方式2 通过对象的序列化实现(推荐)
public Object deepClone(){
// 创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
// 序列化操作
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this); // 当前这个对象以对象流的方式输出
// 反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
DeepProtoType copyObj = (DeepProtoType)ois.readObject();
return copyObj;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
107
1
package cn.xxm.gof23.creational.prototype.deepclone;2
3
import java.io.*;4
5
/**6
* @program: gof237
* @link: 55864455@qq.com8
* @author: Mr.Xxm9
* @create: 2020-02-15 14:4610
**/11
public class DeepProtoType implements Serializable,Cloneable {12
13
private static final long serialVersionUID = 5180880872263164878L;14
15
private String name;16
private DeepCloneableTarget deepCloneableTarget; // 引用类型17
18
public DeepProtoType() {19
}20
21
22
public String getName() {23
return name;24
}25
26
public void setName(String name) {27
this.name = name;28
}29
30
public DeepCloneableTarget getDeepCloneableTarget() {31
return deepCloneableTarget;32
}33
34
public void setDeepCloneableTarget(DeepCloneableTarget deepCloneableTarget) {35
this.deepCloneableTarget = deepCloneableTarget;36
}37
38
39
40
public String toString() {41
return "DeepProtoType{" +42
"name='" + name + '\'' +43
", deepCloneableTarget=" + deepCloneableTarget +44
'}';45
}46
47
/**48
* 深拷贝-方式1 使用clone方法49
* @return50
* @throws CloneNotSupportedException51
*/52
53
protected Object clone() throws CloneNotSupportedException {54
Object deep = null;55
56
// 这里完成对基本数据类型(属性)和String的克隆57
deep = super.clone();58
59
// 对引用类型的属性,进行单独处理60
DeepProtoType deepProtoType = (DeepProtoType) deep;61
DeepCloneableTarget deepCloneableTarget = (DeepCloneableTarget) deepProtoType.getDeepCloneableTarget().clone();62
deepProtoType.setDeepCloneableTarget(deepCloneableTarget);63
64
return deep;65
}66
67
68
// 深拷贝 - 方式2 通过对象的序列化实现(推荐)69
public Object deepClone(){70
// 创建流对象71
ByteArrayOutputStream bos = null;72
ObjectOutputStream oos = null;73
74
ByteArrayInputStream bis = null;75
ObjectInputStream ois = null;76
77
try {78
// 序列化操作79
bos = new ByteArrayOutputStream();80
oos = new ObjectOutputStream(bos);81
oos.writeObject(this); // 当前这个对象以对象流的方式输出82
83
// 反序列化84
bis = new ByteArrayInputStream(bos.toByteArray());85
ois = new ObjectInputStream(bis);86
87
DeepProtoType copyObj = (DeepProtoType)ois.readObject();88
return copyObj;89
} catch (Exception e) {90
e.printStackTrace();91
return null;92
}finally {93
try {94
bos.close();95
oos.close();96
bis.close();97
ois.close();98
} catch (Exception e) {99
e.printStackTrace();100
}101
}102
}103
104
105
106
}107
/**
* @program: gof23
* @link: 55864455@qq.com
* @author: Mr.Xxm
* @create: 2020-02-15 15:04
**/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
DeepProtoType p = new DeepProtoType();
p.setName("松江");
p.setDeepCloneableTarget(new DeepCloneableTarget("大牛","小妞"));
// 方式1 完成深拷贝
//DeepProtoType p2 = (DeepProtoType) p.clone();
// 方式2 完成深拷贝
DeepProtoType p2 = (DeepProtoType) p.deepClone();
System.out.println("p.name = " + p.getName() +" p.getDeepCloneableTarget="+p.getDeepCloneableTarget().hashCode());
System.out.println("p2.name = " + p2.getName() +" p2.getDeepCloneableTarget="+p2.getDeepCloneableTarget().hashCode());
}
}22
1
/**2
* @program: gof233
* @link: 55864455@qq.com4
* @author: Mr.Xxm5
* @create: 2020-02-15 15:046
**/7
public class Client {8
public static void main(String[] args) throws CloneNotSupportedException {9
DeepProtoType p = new DeepProtoType();10
p.setName("松江");11
p.setDeepCloneableTarget(new DeepCloneableTarget("大牛","小妞"));12
13
// 方式1 完成深拷贝14
//DeepProtoType p2 = (DeepProtoType) p.clone();15
16
// 方式2 完成深拷贝17
DeepProtoType p2 = (DeepProtoType) p.deepClone();18
19
System.out.println("p.name = " + p.getName() +" p.getDeepCloneableTarget="+p.getDeepCloneableTarget().hashCode());20
System.out.println("p2.name = " + p2.getName() +" p2.getDeepCloneableTarget="+p2.getDeepCloneableTarget().hashCode());21
}22
}

浙公网安备 33010602011771号