名称:Prototype(原型模式)
 
   意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
 
   适用环境:当一个系统应该独立于它的产品创建、构成和表示时,要使用Prototype模式;以及要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;或者 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

    结构图:如下

 Prototype.gif

java中提供了clone()来实现对象克隆。所以prototype模式变得了很简单。

只要实现接口Cloneable就可以了

package prototype;
import java.util.Date;
import java.io.*;
public class Monkey implements Cloneable{
    
private int height;
    
private int weight;
    
private GoldRingedStaff staff;
    
private Date birthDate;
    
    
public Monkey(){
        birthDate
=new Date();
        staff
=new GoldRingedStaff();
    }
 
         
//浅拷贝
       
  public Object clone(){
        Monkey temp
=null;
        
try{
            temp
=(Monkey)super.clone();
        }
catch(CloneNotSupportedException e){
        }
finally{
            
return temp;
        }

        
    }

}

深拷贝:上面简单的调用了Object的clone()方法,此时只是进行了浅拷贝,若Monkey里含有对象成员staff,则用上述方法克隆出的对象与原对象指向同一个对象staff,显然有时候这并不满足要求。
深拷贝是指:被复制的对象的所有变量都含有与原来对象相同的值,除去那些引用其它变量的对象。
在Java中可以利用串行化(Serivalized)来实现深拷贝,先使一个对象实现Serializable接口,然后把对象(对象的一个拷贝)写入一个流中,后再从流里读出来,这样便可重复创建对象。
package prototype;
import java.util.Date;
import java.io.*;
public class Monkey implements Cloneable,Serializable{
    
private int height;
    
private int weight;
    
private GoldRingedStaff staff;   //GoldRingedStaff必须实现Serializable接口
    
private Date birthDate;
    
    
public Monkey(){
        birthDate
=new Date();
        staff
=new GoldRingedStaff();
    }

        
//深拷贝
    public Object deepClone()throws IOException,ClassNotFoundException{
        ByteArrayOutputStream bo
=new ByteArrayOutputStream();
        ObjectOutputStream oo
=new ObjectOutputStream(bo);
        oo.writeObject(
this); //写入流中
        ByteArrayInputStream bi
=new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi
=new ObjectInputStream(bi);
        
return oi.readObject(); //从流中读出
    }

    }

使用原型模式,有以下结论:
         1.在运行时,可以根据需要,以复制的方式增加和删除类。(登记型原形模式)
         2.可以基于程序条件,在运行时修改一个类的内部数据表示。
         3.还可以在运行时指定新的对象,而无需创建一系列类和继承结构。


参考资料:《Java与模式》
                    《Java设计模式》
                     http://www.lvjiyong.com/books/DesignPatterns/16.html