原型模式:也是一种创建型模式,它关注的是系统中需要创建大量对象,但对象之间有很多相似之处或者对象基本相同。
原型模式有两种不同的实现:1、简单形式 2、登记形式
一、简单形式
public interface Prototype{ public Object clone(); } public class P1 implements Prototype{ public Prototype clone(){ Prototype p=new P1; return p; } } public class P2 implements Prototype{ public Prototype clone(){ Prototype p=new P2(); return p; } }
//客户端 public class client{ Prototype prototype; public client(Prototype prototype){ this.prototype=prototype; } //clone public void opration(){ Prototype p=prototype.clone(); } }
二、登记形式 多一个原型管理器(PrototypeManger),作用是记录每个创建的对象。
public class PrototypeManager(){ private static Map<String ,Prototype> prototypeMap=new HashMap<String,Prototype>(); private PrototypeManager(){ } public synchronized static Prototype getPrototype(String key){ return prototypeMap.get(key); } public synchronized static void setPrototype(String key,Prototype p){ prototypeMap.put(key,p); } }
//客户端 public class client{ Prototype p1=new xxxPrototype();//只是一个实现 PrototypeManager.setPrototype("p1",p1); //clone Prototype p2=PrototypeManager.getPrototype("p1").clone(); }
简单形式用于单一少量的对象创建上.
登记形式:原型对象数量不固定,或者原型对象在管理器中已经拥有满足要求的原型对象。
clone方法的两种克隆方式:浅克隆和深克隆
浅克隆:不包含对象中引用对象的克隆。只针对(String和基本类型的克隆)。
深克隆:包含对引用对象的,深层引用对象的克隆,注意循环引用的处理。
一、浅克隆:java中实现Cloneable接口,就是一个浅克隆.注:实现Cloneable接口是为了标注为一个可克隆对象。
public class Computer implements Cloneable{ private String name; public Object clone(){ try{ return super.clone(); }catch(CloneNotSupportedException e){ return null; } } } //调用 Computer c=new Computer(); Computer x=c.clone();
二、深克隆:经过对象的序列换与反序列化实现。
public Object deepClone() throws IOException,ClassNotFoundException{ //将对象写入流 ByteArrayOutputSteam bos=new ByteArrayOutputStream(); ObjectOutoutStream oos=new ObjectOutputStream(bos); oos.writeObject(this); //从流中读取对象 ByteArrayInputSteam bis=new ByteArrayInputStream(bos); ObjectInputStream ois=new ObjectInputStream(bis); return ois.readObject(ois); }
这样写的前提是类中的引用对象都是可序列化的,把不能序列化的对象注解@transient。
应用场景:1、当多个调用者要修改一个对象时。
2、当一个对象有很多引用对象,使用clone的效率会高于new。因为在内存中把已有的对象用流输出。
3、有一些对象,比如线程(Thread)对象或Socket对象,是不能简单复制或共享的。不管是使用浅度克隆还是深度克隆,只要涉及这样的间接对象,就必须把间接对象设成transient而不予复制;或者由程序自行创建出相当的同种对象,权且当做复制件使用。