前言
本章讲解原型设计模式的相关概念
方法
1.概念
通过之前的建造者设计模式,我们可以发现可以构建较为复杂的对象。
那么,如果在短时间内要求你创建许多个这样的对象呢?那岂不是很难受。原型设计模式帮我们解决了这一问题!
2.原型设计模式之深浅复制
在讲解原型设计模式之前,我们有必要了解一下克隆(复制)的概念。在Object类中,有一个clone方法用来复制对象,从而避免了我们在创建大量复杂对象时的时间消耗问题。这也是原型设计模式的核心所在。
在复制的时候,又分为浅层复制和深层复制,这一点我们稍后会通过代码进行演示。
1)浅层复制
创建工程如下:
创建需要复制的对象类Car,代码如下:
package prototype;
import java.sql.Date;
/**
* 测试原型模式-浅复制
* 用到复制方法clone需要实现Cloneable接口
* @author jwang
*
*/
public class Car implements Cloneable{
private String name;
private Date hireDate;
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
return obj;
}
public Car() {
}
public Car(String name, Date hireDate) {
super();
this.name = name;
this.hireDate = hireDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
@Override
public String toString() {
return "Car [name=" + name + ", hireDate=" + hireDate + "]";
}
}
其中实现了clone方法可以进行对象的复制。
编写测试类如下:
package prototype;
import java.sql.Date;
public class Test {
public static void main(String[] args) throws Exception{
Date date = new Date(131243545435L);
//设置原型
Car oldCar = new Car("奥迪", date);
System.out.println("原来的车:");
System.out.println(oldCar);
Car newCar = (Car) oldCar.clone();
newCar.setName("奥迪");
System.out.println("新的车:");
System.out.println(newCar);
//判断对象是否相同
System.out.println(oldCar == newCar);
//改变时间,若下面的时间改变,则为浅层复制
date.setTime(1312434324L);
System.out.println("新的车:");
System.out.println(newCar);
}
}
执行结果如下:
从功能上讲,我们的原型模式已经成功,也就是根据一个原型我们可以克隆出一到多个对象。
但是细心的朋友不难发现,我们一旦更改了它们所引用的时间,那么克隆出来的对象的生产日期就会发生变化,这是不对的。
为什么会发生这个问题呢?因为我们在复制对象的时候没有将时间类型进行复制,导致了时间引用相同的问题,一旦引用的时间发生了变化,那么就会出现克隆对象属性被更改的问题。
为了解决上面发生的问题,我们将使用深层复制来进行对象的克隆。
2)深层复制
改变Car类代码如下:
package prototype;
import java.sql.Date;
/**
* 测试原型模式-深复制
* 用到复制方法clone需要实现Cloneable接口
* @author jwang
*
*/
public class Car implements Cloneable{
private String name;
private Date hireDate;
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
Car car = (Car)obj;
//深层复制,将其属性也统统复制
car.hireDate = (Date) this.hireDate.clone();
return obj;
}
public Car() {
}
public Car(String name, Date hireDate) {
super();
this.name = name;
this.hireDate = hireDate;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getHireDate() {
return hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
@Override
public String toString() {
return "Car [name=" + name + ", hireDate=" + hireDate + "]";
}
}
我们依然运行之前的测试方法:
这个时候我们可以发现,我们新对象的生产日期还是和之前老的车一模一样,这样就完成了对象的复制。
思考
原型设计模式的克隆对象方法和普通的new对象方法在效率上有什么不同?
这个大家可以进行一个实验,比如同时创建一千个对象,分别采用普通的new和原型设计模式,比比看谁的用时少。
我这里可以告诉大家,显然原型设计模式在短时间内创造大量对象所耗时间是最少的!!!