原型模式的作用
- 克隆对象
- 假设创建对象的步骤比较多而且繁杂,原型模式可以简化新建对象的步骤
实现原型模式的步骤
- 实现Cloneable接口
- 重写clone() 方法
代码实现
声明一个对象Person,对象中有name和birth两个属性
package com.ycm.prototype.demo01;
import java.util.Date;
/**
* 实现原型模式:
* 1. 实现cloneable接口
* 2.重写该方法
*/
public class Person implements Cloneable {
private String name;
private Date birth;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Person(String name, Date birth) {
this.name = name;
this.birth = birth;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", birth=" + birth +
'}';
}
}
然后再创建一个类Robot用于克隆Person类
package com.ycm.prototype.demo01;
import java.util.Date;
public class Robot {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个Person对象
Date date = new Date();
Person person = new Person("张三",date);
//克隆对象
Person robot = (Person) person.clone();
System.out.println("person->"+person);
System.out.println(person.hashCode());
System.out.println("robot->"+robot);
System.out.println(robot.hashCode());
}
}
将结果打印出来
可以看到他们两个对象的属性完全一样,但是hashCode不一样,说明他们是两个不同空间的对象。
存在问题:浅拷贝
我们再将代码改变一下:
package com.ycm.prototype.demo01;
import java.util.Date;
public class Robot {
public static void main(String[] args) throws CloneNotSupportedException {
//创建一个Person对象
Date date = new Date();
Person person = new Person("张三",date);
//克隆对象
Person robot = (Person) person.clone();
System.out.println("person->"+person);
System.out.println("robot->"+robot);
System.out.println("===============================");
date.setTime(1212121212);
System.out.println("person->"+person);
System.out.println("robot->"+robot);
}
}
结果如下:
其中的date对象是person对象的,不是Robot对象的,但是在修改了person对象的date属性值的时候,robot也跟着改变了
说明:person和robot绑定的date值是同一个值(两个对象都指向同一个引用)。那这是不好的,也称之为浅拷贝。
我们希望拷贝完的对象是一个新的对象,不再和克隆前的对象绑定同一个引用。
解决问题:深拷贝
我们只需要在前面的clone()方法做一些修改
在拷贝对象的同时连同属性也一起拷贝
那我们再来看下输出结果:
可以看到修改的只是person的date,而robot的date并没有改变