您的位置:首页 > 其它

设计模式--原型模式

2015-10-12 23:06 176 查看
定义:

用原型实例创建对象的种类,并且通过拷贝这些原型创建新的对象。

在java中,其实原型模型已经应用到了平常的操作中,即只要类实现了Cloneable接口,那么这个类的对象,就可以通过其父类的clone()方法被复制,这就是原型模型。

但是要注意以下几点:

1、通过复制的方式产生了一个对象,构造方法是不会执行的,因为Object类的clone()方法的原理是从内存中以二进制流的方式进行拷贝,重新分配一个内存块。

2、深拷贝和浅拷贝的问题,Object类提供的clone()方法只拷贝对象本身,而对其对象内部的数组、引用对象都不拷贝,复制出来的对象中的引用类型的成员变量,还是指向原生对象的内部的引用类型对象的地址,这叫做浅拷贝。这是一种不安全的方式,若要避免这样的方式,就要使用深拷贝,即在复制对象的时候,再把该对象中的引用类型的成员变量复制一次,就实现了深拷贝。

3、既然要使用对象复制的功能,那么就不应该使用final关键字,clone和final是冲突的。

下面是源代码:

/**

* Object类提供的clone()方法只拷贝对象本身,而对其对象内部的数组、引用对象都不拷贝,复制出来的对象中的引用类型

* 的成员变量,还是指向原生对象的内部的引用类型对象的地址,这叫做浅拷贝。这是一种不安全的方式,若要避免这样的方

* 式,就要使用深拷贝,即在复制对象的时候,再把该对象中的引用类型的成员变量复制一次,就实现了深拷贝。

*/

public class Prototype implements Cloneable {

//这里有一个引用类型的成员变量,所以在clone()中,要实现对对象的深拷贝

private ArrayList<String> arrayList=new ArrayList<String>();

/*

* 构造函数,注意:在调用clone()方法进行对象复制的时候,是不会执行构造函数的,因为

* Object类的clone()方法的原理是从内存中以二进制流的方式进行拷贝,重新分配一个内存块。

*/

public Prototype(){

System.out.println("Construct is invoked...");

}

//重写父类中的clone方法,实现对象的复制

@SuppressWarnings("unchecked")

@Override

public Prototype clone() throws CloneNotSupportedException {

Prototype prototype=null;

prototype=(Prototype)super.clone();

prototype.arrayList=(ArrayList<String>)this.arrayList.clone();//深拷贝

return prototype;

}

//setter/getter方法

public void setValue(String value){

this.arrayList.add(value);

}

public ArrayList<String> getValues(){

return this.arrayList;

}

}

public class Client {

public static void main(String[] args) throws CloneNotSupportedException {

Prototype p1=new Prototype();

p1.setValue("piao");

System.out.println(p1.getValues());

//因为在p1中对引用对象已经进行了赋值,所以p2拷贝的是p1赋值之后的对象,

//也就相应的把赋到引用对象中的值一起拷贝过来了,所以在p2是对当前状态

//的p1对象进行的拷贝。

Prototype p2=p1.clone();

p2.setValue("suo");

p2.setValue("datou");

System.out.println(p2.getValues());

}

}

原型模型的优点:

1、因为原型模型使用的是内存二进制流的拷贝,所以要比直接new一个对象效率高很多。

2、逃避构造函数的约束,这个即是优点,又是缺点。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: