您的位置:首页 > 编程语言 > Java开发

java原型模式(Prototype)-创建型

2016-07-03 15:56 489 查看

意图

通过给出一个原型对象来指明所要创建的对象的类型,人后用复制这个原型对象的方法创建出更多同类型的对象。

类图与角色



原型接口(Prototype):具体原型必须实现的接口,Java中的Cloneable接口。
具体原型(Concrete Prototype):对原型接口的实现。

Java对原型模式的内在支持

Java的所有类都继承自Object类,Object类提供了方法clone()进行对象复制,子类可以重写该方法提供满足自己需要的复制方法。
protected Object clone()
原型模式主要用于对象的复制,在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知Java虚拟机可以安全地在这个类上使用clone方法。通过调用这个clone()方法可以得到一个对象的复制。由于Object对象本身并不实现Cloneable接口,因此如果所考虑的类没有实现Cloneable接口时,调用clone方法会抛出CloneNotSupportException异常。

实例

由于Object的clone方法作用域是protected类型的,一般的类无法调用,因此,Prototype类需要将clone方法的作用域修改为public。

class Prototype implements Cloneable{
private String name;
private int age;
@Override
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
public Prototype(String name,int age){
this.name=name;
this.age=age;
}
public void show(){
System.out.println("姓名:"+name+";年龄:"+age) ;
}
}
class test  {
public static void main (String[] args) throws java.lang.Exception{
Prototype prototype = new Prototype("void",25);
prototype.show();
Prototype copy=prototype.clone();
copy.show();
}
}

深复制和浅复制

浅复制:Object类的clone方法只会拷贝对象中的基本的数据类型,而所有的对象引用(包括数组、容器)都仍然指向原来的对象。

深复制。在浅复制基础上,将所有对象引用指向的对象复制一遍,并将对象引用指向复制后的新对象。
class Prototype implements Cloneable{
private ArrayList<Integer> list = new ArrayList<Integer>();
public Prototype(){
list.add(1);list.add(3);list.add(5);
}
@SuppressWarnings("unchecked")
@Override
public Prototype clone(){
Prototype prototype = null;
try{
prototype = (Prototype)super.clone();
prototype.list = (ArrayList<Integer>) this.list.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return prototype;
}
public ArrayList<Integer> getList(){
return list;
}
public void show(){
for(Integer i:list){
System.out.print(i+" ");
}
}
}
class test  {
public static void main (String[] args) throws java.lang.Exception{
Prototype prototype = new Prototype();
prototype.show();
System.out.println();
Prototype copy=prototype.clone();
copy.show();
System.out.println();
System.out.println(prototype.getList()==copy.getList());
}
}

利用序列化来做深复制

把对象写到流里的过程是序列化过程,将对象从流中读出来称为反序列化过程。在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象写到一个流里,再从流里读回来,便可以重建对象。
这样做的前提是对象以及对象内部所有引用到的对象都是可序列化的 ,否则,需要将那些不可序列化的对象设置为transient,排除在复制过程之外。

适用场景

当要实例化的类是在运行时刻指定时,例如,通过动态装载;

建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便的时候。

优点

使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。

使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: