原型模式Prototype

原型模式:也是一种创建型模式,它关注的是系统中需要创建大量对象,但对象之间有很多相似之处或者对象基本相同。

原型模式有两种不同的实现: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而不予复制;或者由程序自行创建出相当的同种对象,权且当做复制件使用。

猜你喜欢

转载自wdt1988520.iteye.com/blog/1964149