定义: 用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
主要用于创建对象
原型模式实现只需要实现一个接口 重写clone()方法 。
我们实现中 会有深拷贝和浅拷贝两种情况。
创建一个羊类 作为prototype
public class Sheep{
/**
* name名字
* creatTime 创建时间
*/
private String name;
private Date creatTime;
public Sheep() {
}
public Sheep(String name, Date creatTime) {
this.name = name;
this.creatTime = creatTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", creatTime=" + creatTime +
'}';
}
}
实现一个Cloneable的接口
重写clone方法
/**
* 克隆的步骤:
* 1.实现一个接口 Cloneable
* 2.重写一个方法
* 羊的原型
* @create: 2021/6/28
* @author: Tony Stark
*/
public class Sheep implements Cloneable{
/**
* name名字
* creatTime 创建时间
*/
private String name;
private Date creatTime;
/**
* 克隆的方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Sheep() {
}
public Sheep(String name, Date creatTime) {
this.name = name;
this.creatTime = creatTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", creatTime=" + creatTime +
'}';
}
}
创建一个克隆对象的客户端
先创建一个原型 羊的对象
public class Client {
public static void main(String[] args) {
//创建一个原型对象
Date date = new Date();
Sheep sheep1 = new Sheep("喜洋洋",date);
System.out.println("sheep1==>"+sheep1);
System.out.println("sheep1==>hash"+sheep1.hashCode());
}
}
我们克隆出一只羊
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个原型对象
Date date = new Date();
Sheep sheep1 = new Sheep("喜洋洋",date);
System.out.println("sheep1==>"+sheep1);
System.out.println("sheep1==>hash"+sheep1.hashCode());
//sheep1 克隆出一个 sheep2 克隆羊
Sheep sheep2 = (Sheep)sheep1.clone();
System.out.println("sheep2==>"+sheep2);
System.out.println("sheep2==>hash"+sheep2.hashCode());
}
}
可以看出我们已经成功克隆出来一模一样的对象了
小问题
这时候我们sheep1 和sheep2共同用了一个date对象
但是如果我们修改data对象的值 我们会发现一个问题
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个原型对象
Date date = new Date();
Sheep sheep1 = new Sheep("喜洋洋",date);
Sheep sheep2 = (Sheep)sheep1.clone();
System.out.println("sheep1==>"+sheep1);
System.out.println("sheep2==>"+sheep2);
date.setTime(123213);
//sheep1 克隆出一个 sheep2 克隆羊
//克隆出来的对象跟原来是一模一样的
System.out.println("sheep1==>"+sheep1);
System.out.println("sheep2==>"+sheep2);
}
}
此时我们可以发现两个对象的值都被更改了 这就是浅克隆的一些弊端
我们要实现深克隆有多种方式 可以序列化与反序列化 我们这里直接采用改造克隆方法
/**
* 克隆的方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
//实现深克隆 或者 序列化与反序列化
Sheep s=(Sheep)obj;
//将对象的属性也进行克隆
s.creatTime = (Date) this.creatTime.clone();
return obj;
}
当然此时如果属性较多我们这样做就相形见绌了
但现在只有一个字段 是可以的
测试
我们可以看到只有一个 对象被更改了
完整代码
public class Sheep implements Cloneable{
/**
* name名字
* creatTime 创建时间
*/
private String name;
private Date creatTime;
/**
* 克隆的方法
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
//实现深克隆 或者 序列化与反序列化
Sheep s=(Sheep)obj;
//将对象的属性也进行克隆
s.creatTime = (Date) this.creatTime.clone();
return obj;
}
public Sheep() {
}
public Sheep(String name, Date creatTime) {
this.name = name;
this.creatTime = creatTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreatTime() {
return creatTime;
}
public void setCreatTime(Date creatTime) {
this.creatTime = creatTime;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", creatTime=" + creatTime +
'}';
}
}
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个原型对象
Date date = new Date();
Sheep sheep1 = new Sheep("喜洋洋",date);
Sheep sheep2 = (Sheep)sheep1.clone();
System.out.println("sheep1==>"+sheep1);
System.out.println("sheep2==>"+sheep2);
date.setTime(123213);
//sheep1 克隆出一个 sheep2 克隆羊
System.out.println("sheep1==>"+sheep1);
System.out.println("sheep2==>"+sheep2);
}
}