原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象!
需要实现Cloneable接口重写clone()方法或实现Serializable 接口
如果不实现Cloneable接口将会报不支持克隆的错误
/**
* 原型模式 实现Cloneable接口
*/
public class Demo implements Cloneable{
private String name ;
private Date createtime;
@Override
protected Object clone() throws CloneNotSupportedException {
//浅克隆 return super.clone();
//深克隆
Object obj = super.clone();
Demo de = (Demo) obj;
de.createtime= (Date) this.createtime.clone();
return obj;
}
//getset tostring 构造方法省略
}
/**
* 原型模式 Serializable
*/
public class Demo2 implements Serializable {
private String name ;
private Date createtime;
//通过序列化进行深克隆
public Demo2 deepclone() throws Exception {
//将对象写入流中,
ByteArrayOutputStream bao = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bao);
oos.writeObject(this);
//将对象取出来
ByteArrayInputStream bi = new ByteArrayInputStream(bao.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bi);
return (Demo2)ois.readObject();
}
}
/**
* 客户端:克隆
*/
public class Clonedemo1 {
public static void main(String[] args) throws Exception {
//实现Cloneable接口
Date date = new Date();
Demo demo = new Demo("yaoheng",date);
//d 克隆 democlone
Object democlone = demo.clone();
System.out.println("demo1:"+demo);
System.out.println("demo1hashcode:"+demo.hashCode());
System.out.println("demo2:"+democlone);
System.out.println("demo2hashcode:"+democlone.hashCode());
date.setTime(434312515);
System.out.println("demo1:"+demo);
System.out.println("demo2:"+democlone);
//实现Serializable
Date date1 = new Date();
Demo2 demo2 = new Demo2("yaoheng",date1);
//d2 克隆 demo2clone
Demo2 demo2clone = demo2.deepclone();
System.out.println("demo1:"+demo2);
System.out.println("demo1hashcode:"+demo2.hashCode());
System.out.println("demo2:"+demo2clone);
System.out.println("demo2hashcode:"+demo2clone.hashCode());
date.setTime(434312515);
System.out.println("demo1:"+demo2);
System.out.println("demo2:"+demo2clone);
}
}
在原型模式中有两个概念我们需要了解一下,就是浅克隆和深克隆的概念。按照我的理解,浅克隆只是复制了基础属性,列如八大基本类型,然而引用类型实际上没有复制,只是将对应的引用给复制了!复制地址。
原型模式的优缺点
原型模式作为一种快速创建大量相同或相似的对象方式,在软件开发种的应用较为广泛,很多软件提供的CTRL+C和CTRL+V操作的就是原型模式的典型应用!
优点
当创建的对象实例较为复杂的时候,使用原型模式可以简化对象的创建过程!
扩展性好,由于写原型模式的时候使用了抽象原型类,在客户端进行编程的时候可以将具体的原型类通过配置进行读取。
可以使用深度克隆来保存对象的状态,使用原型模式进行复制。当你需要恢复到某一时刻就直接跳到。比如我们的idea种就有历史版本,或则SVN中也有这样的操作。非常好用!
缺点
需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的里面,当对已有的类经行改造时需要修改源代码,违背了开闭原则。
在实现深克隆的时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用的时候,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现相对麻烦。