1.传统方式解决克隆羊问题
1.问题描述

2.类图

3.目录结构

4.代码实现
1.Sheep.java
package com.sun.tradition;
public class Sheep {
private String name;
private int age;
private String color;
public Sheep(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
}
2.Client.java
package com.sun.tradition;
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("tom", 1, "白色");
Sheep sheep1 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep2 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep3 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep4 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep5 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep6 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep7 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep8 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
Sheep sheep9 = new Sheep(sheep.getName(), sheep.getAge(), sheep.getColor());
System.out.println(sheep);
}
}
5.优缺点分析

2.原型模式解决克隆羊问题(浅拷贝)
1.基本介绍

2.类图

3.目录结构

4.代码实现
1.Sheep.java 实现Cloneable接口的clone方法,使用原型模式来实现克隆
package com.sun.improve;
public class Sheep implements Cloneable{
private String name;
private int age;
private String color;
public Sheep(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
@Override
protected Sheep clone() throws CloneNotSupportedException {
return (Sheep) super.clone();
}
}
2.Client.java
package com.sun.improve;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheep = new Sheep("tom", 1, "白色");
Sheep clone = sheep.clone();
Sheep clon2 = sheep.clone();
Sheep clon3 = sheep.clone();
Sheep clon4 = sheep.clone();
System.out.println(clone);
}
}
3.原型模式在Spring框架中的源码分析
1.基本介绍

2.解释
- 在Spring中配置一个bean的时候,有一个scope属性可以选择配置prototype(原型模式)
- 当配置了这个参数,每次getBean的时候就相当于使用原型模式创建了一个新的对象,然后将原对象的属性浅拷贝到这个新的对象
4.深拷贝
1.默认的原型模式为浅拷贝
1.在Sheep.java中添加一个引用类型的数组

2.在Client.java测试克隆的羊和原来的羊的属性是不是一个数组


3.结果表明,默认的原型模式克隆出来的对象,会将引用类型的属性指向原型的属性,共享内存空间,也就是浅拷贝
2.浅拷贝与深拷贝
1.浅拷贝

2.深拷贝

5.实现深拷贝的两种方式
1.重写clone方法实现深拷贝
1.DeepCloneableTarget.java
package com.sun.deepcopy01;
import java.io.Serializable;
public class DeepCloneableTarget implements Serializable, Cloneable {
public static final long serialVersionUID = 1L;
private String name;
private int[] arr;
public DeepCloneableTarget(String name, int[] arr) {
this.name = name;
this.arr = arr;
}
@Override
protected DeepCloneableTarget clone() throws CloneNotSupportedException {
DeepCloneableTarget clone = (DeepCloneableTarget) super.clone();
int[] copyArr = new int[arr.length];
if (arr != null) {
int j = 0;
for (int i : arr) {
copyArr[j ++] = i;
}
}
clone.arr = copyArr;
return clone;
}
public int[] getArr() {
return arr;
}
}
2.Client.java
package com.sun.deepcopy01;
import java.util.Arrays;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
DeepCloneableTarget deepCloneableTarget = new DeepCloneableTarget("sunxiansheng", new int[]{1, 2, 3});
DeepCloneableTarget clone = deepCloneableTarget.clone();
System.out.println(deepCloneableTarget.getArr() == clone.getArr());
System.out.println(Arrays.toString(deepCloneableTarget.getArr()));
System.out.println(Arrays.toString(clone.getArr()));
}
}
3.结果

2.对象序列化实现深拷贝(推荐)
1.DeepCloneableTarget.java
package com.sun.deepcopy02;
import java.io.*;
public class DeepCloneableTarget implements Serializable, Cloneable {
public static final long serialVersionUID = 1L;
private String name;
private int[] arr;
public DeepCloneableTarget(String name, int[] arr) {
this.name = name;
this.arr = arr;
}
public int[] getArr() {
return arr;
}
public DeepCloneableTarget deepClone() {
ByteArrayOutputStream byteArrayOutputStream = null;
ObjectOutputStream objectOutputStream = null;
ByteArrayInputStream byteArrayInputStream = null;
ObjectInputStream objectInputStream = null;
try {
byteArrayOutputStream = new ByteArrayOutputStream();
objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(this);
byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
objectInputStream = new ObjectInputStream(byteArrayInputStream);
DeepCloneableTarget copyObject = (DeepCloneableTarget) objectInputStream.readObject();
return copyObject;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
if (byteArrayOutputStream != null) {
byteArrayOutputStream.close();
}
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (byteArrayInputStream != null) {
byteArrayInputStream.close();
}
if (objectInputStream != null) {
objectInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.Client.java
package com.sun.deepcopy02;
import java.util.Arrays;
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
DeepCloneableTarget deepCloneableTarget = new DeepCloneableTarget("sunxiansheng", new int[]{1, 2, 3});
DeepCloneableTarget clone = deepCloneableTarget.deepClone();
System.out.println(deepCloneableTarget.getArr() == clone.getArr());
System.out.println(Arrays.toString(deepCloneableTarget.getArr()));
System.out.println(Arrays.toString(clone.getArr()));
}
}
3.结果

3.原型模式的注意事项
