原型模式
将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
1.编写测试所需JavaBean
实现Cloneable接口,重写clone方法
Sheep:模拟浅克隆
Sheep2:模拟深克隆
package com.bjsxt.prototype;
import java.io.Serializable;
import java.util.Date;
/**
* 克隆羊多利
* @author WL20180732
*
*/
public class Sheep implements Cloneable, Serializable{
private String sname;
private Date birthdy;
public Sheep(String sname, Date birthdy) {
this.sname = sname;
this.birthdy = birthdy;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Date getBirthdy() {
return birthdy;
}
public void setBirthdy(Date birthdy) {
this.birthdy = birthdy;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone(); // 直接调用Object的克隆方法,浅克隆
return obj;
}
}
package com.bjsxt.prototype;
import java.util.Date;
/**
* 测试深复制
* @author WL20180732
*
*/
public class Sheep2 implements Cloneable{
private String sname;
private Date birthdy;
public Sheep2(String sname, Date birthdy) {
this.sname = sname;
this.birthdy = birthdy;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Date getBirthdy() {
return birthdy;
}
public void setBirthdy(Date birthdy) {
this.birthdy = birthdy;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone(); // 直接调用Object的克隆方法
// 添加如下代码实现深复制
Sheep2 s = (Sheep2) obj;
s.birthdy = (Date)this.birthdy.clone(); // 把属性也进行拷贝
return obj;
}
}
2.测试原型模式(浅克隆)
package com.bjsxt.prototype;
import java.util.Date;
/**
* 测试原型模式(浅克隆)
* @author WL20180732
*
*/
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(122121545454L);
Sheep sheep = new Sheep("少利", date);
System.out.println(sheep);
Sheep sheep2 = (Sheep) sheep.clone();
sheep2.setSname("多利");
System.out.println(sheep2);
System.out.println(sheep2.getSname());
System.out.println(date == sheep2.getBirthdy()); // true sheep和sheep2使用了同一个日期对象,所以是浅克隆
System.out.println(sheep == sheep2); // false,不是相同的对象,但是值相同
}
}
3.测试深克隆
package com.bjsxt.prototype;
import java.util.Date;
/**
* 原型模式(深拷贝)
* @author WL20180732
*
*/
public class Client2 {
public static void main(String[] args) throws CloneNotSupportedException {
Date date = new Date(122121545454L);
Sheep2 sheep = new Sheep2("少利", date);
Sheep2 sheep2 = (Sheep2) sheep.clone();
date.setTime(1234567654321L);
System.out.println(sheep.getBirthdy()); // sheep的出生日期更改不会影响sheep2
System.out.println(sheep2.getBirthdy());
System.out.println(sheep == sheep2); // false,不是相同的对象,但是值相同
}
}
4.使用序列化和反序列化的方式实现深复制
package com.bjsxt.prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* 原型模式(深拷贝,使用序列化和反序列化的方式实现深复制)
* @author WL20180732
*
*/
public class Client3 {
public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
Date date = new Date(122121545454L);
Sheep sheep = new Sheep("少利", date);
// Sheep sheep2 = (Sheep) sheep.clone();
// 使用序列化和反序列化实现深复制
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(bos);
os.writeObject(sheep);
byte[] bytes = bos.toByteArray();
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
Sheep sheep2 = (Sheep) ois.readObject(); // 克隆羊
System.out.println(sheep.getBirthdy());
date.setTime(1234567654321L); //修改以前对象的属性,不会影响克隆羊
System.out.println(sheep.getBirthdy()); // sheep的出生日期更改不会影响sheep2
System.out.println(sheep2.getBirthdy());
System.out.println(sheep == sheep2); // false,不是相同的对象,但是值相同
}
}
5.测试通过new和clone方法短时间创建大量对象的效率对比
package com.bjsxt.prototype;
/**
* 测试通过new和clone方法短时间创建大量对象的效率对比
* 如果需要短时间创建大量对象,且new的过程比较耗时,则clone的效率更高
* @author WL20180732
*
*/
public class Client4 {
public static void main(String[] args) throws CloneNotSupportedException {
testNew(1000);
testClone(1000);
}
public static void testNew(int size) {
long start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
Laptop t = new Laptop();
}
long end = System.currentTimeMillis();
System.out.println("new方式创建耗时:" + (end - start) );
}
public static void testClone(int size) throws CloneNotSupportedException {
long start = System.currentTimeMillis();
Laptop t = new Laptop();
for (int i = 0; i < size; i++) {
Laptop temp = (Laptop) t.clone();
}
long end = System.currentTimeMillis();
System.out.println("clone方式创建耗时:" + (end - start) );
}
}
/**
* 笔记本电脑
* @author WL20180732
*
*/
class Laptop implements Cloneable{
public Laptop() {
try {
// 模拟创建一个该类对象非常耗时的场景
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}