如果有需求要多次创建同一个类,可以多new几个对象。但这样势必会使代码繁琐臃肿,拓展性也不会好。
这个时候需要一种解决方案让我们创建多个类的过程变得简单,原型模式就应运而生。
原型模式之浅拷贝
//克隆羊类
public class Sheep implements Cloneable {
private String name;
private Integer age;
private String color;
private Sheep friend;
public Sheep(String name, Integer age, String color, Sheep friend) {
this.name = name;
this.age = age;
this.color = color;
this.friend = friend;
}
public Sheep getFriend() {
return friend;
}
public void setFriend(Sheep friend) {
this.friend = friend;
}
public Sheep(String name, Integer 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 Integer getAge() {
return age;
}
public void setAge(Integer 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
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
", friend=" + friend +
'}';
}
@Override
protected Object clone() {
Sheep sheep = null;
try {
sheep = (Sheep) super.clone();
} catch (Exception e) {
System.out.println(e);
}
return sheep;
}
}
import com.teasir.prototype.improve.Sheep;
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("多莉", 6, "白色");
sheep.setFriend(new Sheep("汤姆", 5, "黑色"));
Sheep sheep1 = (Sheep) sheep.clone();
Sheep sheep2 = (Sheep) sheep.clone();
Sheep sheep3 = (Sheep) sheep.clone();
Sheep sheep4 = (Sheep) sheep.clone();
Sheep sheep5 = (Sheep) sheep.clone();
System.out.println(sheep);
System.out.println(sheep1+"拷贝friend地址:"+sheep1.getFriend().hashCode());
System.out.println(sheep2+"拷贝friend地址:"+sheep2.getFriend().hashCode());
System.out.println(sheep3+"拷贝friend地址:"+sheep3.getFriend().hashCode());
System.out.println(sheep4+"拷贝friend地址:"+sheep4.getFriend().hashCode());
System.out.println(sheep5+"拷贝friend地址:"+sheep5.getFriend().hashCode());
}
/*
* 总结:原型模式解决克隆羊问题,比直接new更具拓展性
* 实现Cloneable接口,重新其中的clone方法
*
* spring创建原型bean的时候用到了原型模式(scope)
*
* clone方法实现的就是浅拷贝
* 浅拷贝定义:基本数据类型直接进行值传递,引用数据类型直接传递引用的地址
* 深拷贝定义:基本数据类型直接进行值传递,引用数据类型要对整个对象进行拷贝。
* */
}
原型模式之深拷贝
//克隆羊
import java.io.*;
public class Sheep implements Cloneable, Serializable {
private String name;
private Integer age;
private String color;
private Sheep friend;
public Sheep() {
}
public Sheep(String name, Integer age, String color, Sheep friend) {
this.name = name;
this.age = age;
this.color = color;
this.friend = friend;
}
public Sheep getFriend() {
return friend;
}
public void setFriend(Sheep friend) {
this.friend = friend;
}
public Sheep(String name, Integer 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 Integer getAge() {
return age;
}
public void setAge(Integer 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
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
", friend=" + friend +
'}';
}
/*
* 深拷贝方案一:clone
* */
@Override
protected Object clone() {
Sheep sheep = null;
try {
sheep = (Sheep) super.clone();
sheep.friend = (Sheep) friend.clone();
} catch (Exception e) {
System.out.println(e);
}
return sheep;
}
/*
* 深拷贝方案二:序列化
* */
public Object dpClone() {
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);
Sheep copyObj=(Sheep) ois.readObject();
return copyObj;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
try {
ois.close();
bis.close();
oos.close();
bos.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep("多莉", 6, "白色");
sheep.setFriend(new Sheep("汤姆", 5, "黑色"));
/* Sheep sheep1 = (Sheep) sheep.clone();
Sheep sheep2 = (Sheep) sheep.clone();
Sheep sheep3 = (Sheep) sheep.clone();
System.out.println(sheep);
System.out.println(sheep1+"拷贝friend地址:"+sheep1.getFriend().hashCode());
System.out.println(sheep2+"拷贝friend地址:"+sheep2.getFriend().hashCode());
System.out.println(sheep3+"拷贝friend地址:"+sheep3.getFriend().hashCode());*/
Sheep sheep1 = (Sheep) sheep.dpClone();
Sheep sheep2 = (Sheep) sheep.dpClone();
Sheep sheep3 = (Sheep) sheep.dpClone();
System.out.println(sheep);
System.out.println(sheep1+"拷贝friend地址:"+sheep1.getFriend().hashCode());
System.out.println(sheep2+"拷贝friend地址:"+sheep2.getFriend().hashCode());
System.out.println(sheep3+"拷贝friend地址:"+sheep3.getFriend().hashCode());
}
/*
* 总结:深拷贝实现的两种方式:
* 1.单独对引用对象进行clone
* 2.使用对象序列化的方式借流先将类输出再输入获得对象(推荐)
* */
}