原型模式
原型模式顾名思义,就是通过一个原型模板,以此为基础进行对象的创建,新对象的创建。
本质上和CV大法一样,把别人的东西,复制过来,自己再改改就成为了自己的东西。但是和原来的那份又不尽相同,同时原来的那份依旧存在。
结构
原型模式中有以下角色:
抽象原型类规定了具体的原型类模板,必须要实现的clone()方法。具体原型类实现了上述抽象原型类的clone()方法,并且自己作为板子访问类就是来使用clone()方法,来创建新对象的类
实现方式
原型模式的实现方式有两种
浅克隆:创建一个新对象,新对象当中的属性值,和原来对象一摸一样,对于基本的数据类型,里面值一摸一样。对于引用的数据类型,里面值的值也一摸一样,指向同一个地址,换句话就是和原对象共享同一个数据。深克隆:创建一个新对象,新对象当中的属性值,和原来对象一摸一样,但是对于引用类型,指向的不再是原对象地址,而是指向新的地址,但是新地址中的值与原来的对象一摸一样
浅克隆
Java中的Object类当中,给我们提供了clone(),来实现浅克隆,我们只需要Cloneable接口,就可以了。其中Cloneable接口对应的就是上述结构中的抽象原型类。
public class Realizetype implements Cloneable {
public Realizetype() {
System.out.println("具体的原型对象创建完成!");
}
@Override
protected Realizetype clone() throws CloneNotSupportedException {
System.out.println("具体原型复制成功!");
return (Realizetype) super.clone();
}
}
PS: 注意clone返回的类型要进行强制转换,转换成为本类的类型
使用场景
- 对象的创建相当的复杂,可以用原型模式快速的进行床架对象
- 对性能和安全的要求比较高,这样用原型模式创建模式,可以保证创建出的对象结构,属性和之前一摸一样。
深克隆
可惜的是java中并没有给我提供深克隆的接口,所以我们只能自己想办法,深克隆需要把引用类型的属性也进行复制,故此我们需要使用对象,来进行深克隆
public class CitationTest1 {
public static void main(String[] args) throws Exception {
Citation c1 = new Citation();
Student stu = new Student("张三", "西安");
c1.setStu(stu);
//创建对象输出流对象
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\b.txt"));
//将c1对象写出到文件中
oos.writeObject(c1);
oos.close();
//创建对象出入流对象
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\b.txt"));
//读取对象
Citation c2 = (Citation) ois.readObject();
//获取c2奖状所属学生对象
Student stu1 = c2.getStu();
stu1.setName("李四");
//判断stu对象和stu1对象是否是同一个对象
System.out.println("stu和stu1是同一个对象?" + (stu == stu1));
c1.show();
c2.show();
}
}
PS:简单来说深克隆就是通过序列化和反序列化来进行实现,注意如果要进行序列化,其中对应的原型类和原型类中的引用类型要实现Serializable 否则会报NotSerializableException异常。