原型模式

原型模式(Prototype模式)主要用于复制一个已经存在对象实例,而不是去创建它。而被复制的对象称为原型。它比较适用于复杂,耗时和不断变化的对象的生成工作。官方定义说道:

使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象

下面给出Java的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Prototype implements Cloneable{
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
} catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
}
class ConcretePrototype extends Prototype{
public void show(){
System.out.println("show");
}
}
public class Client{
public static void main(String [] args){
ConcretePrototype c = new ConcretePrototype();
ConcretePrototype cp = (ConcretePrototype)c.clone();
}
}

Java中需要具备两个条件:

  • 实现Cloneable接口,这个接口是一个完全空的接口,只是用来标记可以克隆的,必须要实现该接口,否则爆CloneNotSupportException异常

  • 重写Object类中的clone方法,在Object类中,protected native Object clone()可以看出,需要将操作符改成pulbic才能适用

原型模式在性能上比new创建对象好,它是一个native方法,直接操作内存中的二进制流,复制大对象时非常明显。它不会调用对象的构造函数。

Object类里的clone只会拷贝对象中的基本数据类型(及其包装类,String类),对于数组,容器对象,引用等都是浅拷贝;如果实现深拷贝,参考如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Prototype implements Cloneable {
private ArrayList list = new ArrayList();
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
prototype.list = (ArrayList) this.list.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
}

上面的代码注意的是,listprivate类型的,但是在clone方法中却能够使用prototype.list直接访问,真的很暴力。

private针对的是类,而不是对象,因为是在Prototype类中,因此在该类里Prototype对象的私有成员是可以访问的,其他类的对象则不行。