@Tyhj
        
        2019-01-29T09:23:34.000000Z
        字数 1674
        阅读 1340
    设计模式
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新对象
- 类的初始化需要消耗非常多的数据、硬件资源,通过拷贝来避免消耗
 - new 一个对象非常的麻烦,可能需要各种权限
 - 一个对象需要给其他对象使用,而且会被改变,为了保护这个对象,可以使用原型模式
 
其实就是复制一个已存在的实例,来避免重新创建对象的一些麻烦。但是有时候使用拷贝不一定更高效,需要自己来判断是否使用
实现其实很简单,只需要这个类实现Cloneable接口,然后重写一下clone方法就好了,Cloneable接口只是一个标志接口,没有任何方法,clone方法是Object自带的方法,实现了接口才能使用clone方法
随便写个文档的类,保存标题、介绍、图片这些内容,实现Cloneable接口,然后重写一下clone
public class Essay implements Cloneable{private String title;private String introduction;private ArrayList<String> imgs;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}...}
初始化后,拷贝这个类
String title = "原型模式";String introduction = "介绍一";ArrayList<String> imgs = new ArrayList<>();imgs.add("图片一");Essay essay = new Essay(title, introduction, imgs);Essay essay1= (Essay) essay.clone();System.out.println(essay1.toString());
输出拷贝对象如下,其实不重写clone方法也完全可以拷贝出来,就是说默认就会拷贝变量
Essay{title='原型模式', introduction='介绍一', imgs=[图片一]}
但是我们改一下程序,把拷贝过来的对象的值改变一下,再输出原对象的值
essay1.imgs.add("嘿嘿嘿");System.out.println(essay.toString());
输出如下,发现原imgs的值被改变了
Essay{title='原型模式', introduction='介绍一', imgs=[图片一, 嘿嘿嘿]}
这个表明,拷贝的对象只是一个引用了原对象的变量而已,当拷贝对象发生了变化,原对象也变了;
拷贝的对象只是一个引用了原对象的变量,这个就是浅拷贝;在我们改变了拷贝对象的值的时候,原对象也会改变;
深拷贝肯定就是真正意义上的拷贝,拷贝对象不会对原对象产生影响,方法也很简单;我们可以看到其实基本类型是没有引用的,所以拷贝的时候肯定是没有问题的,不用考虑的基本类型;所以只需要在拷贝对象的时候,对于引用型的字段也采用拷贝的形式就可以了;
@Overrideprotected Object clone() throws CloneNotSupportedException {Essay essayClone= (Essay) super.clone();essayClone.imgs= (ArrayList<String>) imgs.clone();return essayClone;}
再次运行,原对象的值的确没有被改变
Essay{title='原型模式', introduction='介绍一', imgs=[图片一]}
但是其中有一个问题就是,如果改变拷贝的String对象的值,原值会不会被改变;其实是不会的,String类比较特殊,因为String是在内存中不可以被改变的对象,String自身没有方法可以改变自身的值;所以要是你的类没有可以改变自身值,也可以不用考虑,本质还是引用,如果用==来判断会返回true
使用原型模式就是为了更高效的创建对象,最好是使用深拷贝,避免影响原始对象
