原型模式Prototype
程序员文章站
2022-06-12 21:42:36
...
原型模式:也是一种创建型模式,它关注的是系统中需要创建大量对象,但对象之间有很多相似之处或者对象基本相同。
原型模式有两种不同的实现: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而不予复制;或者由程序自行创建出相当的同种对象,权且当做复制件使用。