原型模式之------序列化和反序列化
原型模式之通过序列化和反序列化实现深复制
其实,我们什么时候会使用原型模式呢?一般来说,如果创建一个对象是比较耗时的话,我们就会考虑使用原型模式。
但是,在实际的应用中,我们很少会直接使用原型模式。一般来说,原型模式都是和工厂方法模式结合起来使用的。这是要注意的。
//如何通过序列化和反序列化的方式来实现深克隆
/*一个实现了Cloneable和Serializable接口的类*/
package com.lg.prototype;
import java.io.Serializable;
import java.util.Date;
/**
* Created by 鏉庢灉 on 2016/8/7.
*/
public class Sheep implements Serializable,Cloneable {
private String name;
private Date birthday;
public Sheep(String name, Date birthday) {
this.name=name;
this.birthday = birthday;
}
public Sheep(){}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
return obj;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public Date getBirthday() {
return birthday;
}
}
/*通过序列化和反序列化的方式来实现深克隆*/
package com.lg.prototype;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Date;
/**
* Created by 鏉庢灉 on 2016/8/7.
*/
public class Client {
public static void main(String[] args) {
Date date = new Date(1223344455L);
Sheep s1 = new Sheep("少丽", date);
System.out.println(s1.getName());
System.out.println(s1.getBirthday());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
/*这是序列化的过程。将一个对象写入到一个bos中*/
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(s1);
byte[] bytes = bos.toByteArray();
/*这是反序列化的过程*/
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bis);
Sheep s2 = (Sheep) ois.readObject();
/*通过序列化和反序列化以后,即使s1修改了date,但是通过深复制得到的对象的date
* 还是不变的。这是要注意的*/
s1.setBirthday(new Date(12334455555567L));
System.out.println("经过修改了以后的少丽的birthday");
System.out.println(s1.getBirthday());
System.out.println("通过深复制得到的对象的具体的情况");
System.out.println(s2.getName());
System.out.println(s2.getBirthday());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*最后的输出的结果为*/
少丽
Thu Jan 15 11:49:04 CST 1970
经过修改了以后的少丽的birthday
Sat Nov 12 05:39:15 CST 2360
通过深复制得到的对象的具体的情况
少丽
Thu Jan 15 11:49:04 CST 1970
/*通过clone和new方式创建对象的效率上的差异*/
package com.lg.prototype;
/**
* Created by 鏉庢灉 on 2016/8/7.
*/
/*测试分别通过new方式和clone方式创建对象的时候的效率和时间的差异*/
public class Client2 {
public static void testNew(int size) {
long start = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
Computer computer = new Computer();
}
long end = System.currentTimeMillis();
System.out.println("通过new方式所需要的时间为" +(end - start));
}
public static void testClone(int size) {
long start = System.currentTimeMillis();
Computer computer=new Computer();
for (int i = 0; i < size; i++) {
try {
Computer C= (Computer) computer.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("通过clone方式所需要的时间为" +(end - start));
}
public static void main(String[] args) {
testNew(1000);
testClone(1000);
}
}
class Computer implements Cloneable{
/**
* 如果创建一个对象的时间是比较长的
* 模拟耗时
*/
public Computer() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object obj = super.clone();
return obj;
}
}
/*最后的输出的结果为*/
通过new方式所需要的时间为10211
通过clone方式所需要的时间为10
我们可以明显的看到,它们创建对象的时间之间是有明显的差异的。
最后,重申一点,如果创建一个对象的是比较复杂的话,那么我们就会使用原型模式,prototype来进行创建。但是原型模式一般是和工厂方法模式结合起来一起使用的。