原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
形 式:原型模式有两种模式:1. 浅复制(浅克隆)2. 深复制(深克隆)
1. 浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
2. 深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
深克隆
深复制(深克隆):
怎么实现深复制(深克隆)呢?修改一下汽车类和汽车发动机类:
汽车类:
- /*
- * 深克隆
- */
- public class Carimplements Cloneable {
- public int type;
- // 引用的其他对象
- public Engine engine;
- public Object clone() {
- Car temp = null;
- try {
- // 先把自己本身复制
- temp = (Car) super.clone();
- // 为了实现深度克隆,需要将对其他对象(在这里是engine)的引用都复制过去。
- temp.engine = (Engine) engine.clone();
- } catch (CloneNotSupportedException e) {
- // should never happen
- }
- return temp;
- }
- }
/*
* 深克隆
*/
public class Car implements Cloneable {
public int type;
// 引用的其他对象
public Engine engine;
public Object clone() {
Car temp = null;
try {
// 先把自己本身复制
temp = (Car) super.clone();
// 为了实现深度克隆,需要将对其他对象(在这里是engine)的引用都复制过去。
temp.engine = (Engine) engine.clone();
} catch (CloneNotSupportedException e) {
// should never happen
}
return temp;
}
}
发动机类:
- public class Engineimplements Cloneable {
- public int model;
- /**
- * 为了实现深度克隆,需要给在Lay1中被应用的对象lay2)也提供一个自己克隆自身的方法
- */
- public Object clone() {
- Object clone = null;
- try {
- clone = super.clone();
- } catch (CloneNotSupportedException e) {
- }
- return clone;
- }
- }
public class Engine implements Cloneable {
public int model;
/**
* 为了实现深度克隆,需要给在Lay1中被应用的对象lay2)也提供一个自己克隆自身的方法
*/
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
}
return clone;
}
}
客户端调用不变。
运行结果:
- -----创建汽车1-----
- 汽车1款式:1 汽车1的发动机型号:1
- ----汽车1--克隆-->汽车2----
- 汽车2款式:2 汽车2的发动机型号:2
- 汽车1款式:1 汽车1的发动机型号:1
-----创建汽车1-----
汽车1款式:1 汽车1的发动机型号:1
----汽车1--克隆-->汽车2----
汽车2款式:2 汽车2的发动机型号:2
汽车1款式:1 汽车1的发动机型号:1
根据运行结果可以发现,深复制(深克隆)把要复制的对象所引用的对象都复制了一遍。
所以,当设定汽车2的发动机型号为2 时,汽车1的发动机型号还是1,没有变化。
因为,汽车1和汽车2拥有了两个不同的发动机。
利用串行化来做深复制(深克隆):
汽车类
实现了串行(序列)化接口,并使用了在流中读取和写入对象。
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.IOException;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.io.Serializable;
- /*
- * 汽车类
- *
- * 序列化的方式实现深克隆(deep clone)
- */
- public class Carimplements Serializable {
- /**
- * serialVersionUID
- */
- private staticfinal long serialVersionUID = 1859639569305572020L;
- // 汽车款式
- public int type;
- // 引用的其他对象,汽车发动机
- public Engine engine;
- public Object clone() {
- try {
- // 将对象写到流里,把对象写到流里的过程是串行化(Serilization)过程
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
- ObjectOutputStream oo;
- oo = new ObjectOutputStream(bo);
- oo.writeObject(this);
- // 从流里读出来,把对象从流中读出来的并行化(Deserialization)过程
- ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
- ObjectInputStream oi = new ObjectInputStream(bi);
- return (oi.readObject());
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- return null;
- } catch (IOException e) {
- // TODO Auto-generated catch block
- return null;
- }
- }
- }
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/*
* 汽车类
*
* 序列化的方式实现深克隆(deep clone)
*/
public class Car implements Serializable {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1859639569305572020L;
// 汽车款式
public int type;
// 引用的其他对象,汽车发动机
public Engine engine;
public Object clone() {
try {
// 将对象写到流里,把对象写到流里的过程是串行化(Serilization)过程
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo;
oo = new ObjectOutputStream(bo);
oo.writeObject(this);
// 从流里读出来,把对象从流中读出来的并行化(Deserialization)过程
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
return null;
}
}
}
汽车发动机类:
- import java.io.Serializable;
- public class Engineimplements Cloneable, Serializable {
- /**
- * Car对象以及对象内部所有引用到的对象engine都是可串行化的
- */
- private staticfinal long serialVersionUID = -6228724315977120960L;
- public int model;
- }
import java.io.Serializable;
public class Engine implements Cloneable, Serializable {
/**
* Car对象以及对象内部所有引用到的对象engine都是可串行化的
*/
private static final long serialVersionUID = -6228724315977120960L;
public int model;
}
客户端调用不变。
运行结果:
- -----创建汽车1-----
- 汽车1款式:1 汽车1的发动机型号:1
- ----汽车1--克隆-->汽车2----
- 汽车2款式:2 汽车2的发动机型号:2
- 汽车1款式:1 汽车1的发动机型号:1
根据运行结果可以发现,通过串行化的方式也实现了深复制(可克隆)。
所以,当设定汽车2的发动机型号为2 时,汽车1的发动机型号还是1,没有变化。
因为,汽车1和汽车2拥有了两个不同的发动机。