原型化设计模式是一种设计模式,可以简单的理解为克隆模式
首先看一段代码
public class WorldDocument implements Cloneable {
private String mText;
private ArrayList<String> mImages = new ArrayList<>();
public WorldDocument() {
System.out.println("----- 这个是构造函数-------");
}
public String getmText() {
return mText;
}
public void setText(String text){
this.mText = text;
}
public void setmText(String mText) {
this.mText = mText;
}
public ArrayList<String> getmImages(){
return this.mImages;
}
public void addImage(String img){
this.mImages.add(img);
}
@Override
protected Object clone() throws CloneNotSupportedException {
WorldDocument doc = (WorldDocument) super.clone();
doc.mText = this.mText;
doc.mImages = this.mImages;
// doc.mImages = (ArrayList<String>) this.mImages.clone();//这样就是深拷贝
return doc;
}
//打印文档的内容
public void showDocument(){
System.out.println("--------------word content Start-------------");
System.out.println("text: "+this.mText);
System.out.println("Images List: ");
for (String imgs: mImages) {
System.out.println("------------: "+imgs);
}
System.out.println("--------------word content end-------------");
}
}
在这里我们写一个类 实现Cloneable这个接口,写两个测试的属性 mText和mImages,在重写clone()这个方法里我们可以看到这样一段代码
WorldDocument doc = (WorldDocument) super.clone();
也就是调用父类的clone方法,注意调用clone()方法形成的实例是不会调用它的构造函数的
测试类
public static void main(String[] args) throws CloneNotSupportedException {
WorldDocument world = new WorldDocument();
world.setText("文字1");
world.addImage("photo1");
world.addImage("photo2");
world.addImage("photo3");
WorldDocument document2 = (WorldDocument) world.clone();
document2.showDocument();
world.showDocument();
}
测试结果
可以很明显的看到两个对象是完全一样的。下面我们稍作修改
public static void main(String[] args) throws CloneNotSupportedException {
WorldDocument world = new WorldDocument();
world.setText("文字1");
world.addImage("photo1");
world.addImage("photo2");
world.addImage("photo3");
WorldDocument document2 = (WorldDocument) world.clone();
world.setText("修改的文字");
world.addImage("添加的照片");
document2.showDocument();
world.showDocument();
}
再看打印的结果
我们很奇怪的发现了对源文件进行修改的时候只有数组变化,但是文字变量并没有改变,这是为什么呢。这里就涉及到浅拷贝可深拷贝的问题,在这里给大家很简单的说下,如果有兴趣
可以深入的研究这个问题。
浅拷贝可深拷贝 : 浅拷贝是简单的拷贝地址,就像C++里面的指针指针类似,而深拷贝是完全的拷贝,是拷贝堆里面的内容,所以浅拷贝的时候拷贝的内容受源内容影响。
想必说到这里,有人就感觉以后,对面上面的例子好像不是那么回事,其实上面的mText是一个变量,不是引用,所以它不存在浅拷贝和深拷贝问题。而数组就不一样了,数组拷贝的就是栈里面的地址,并没有完全的拷贝对立面的内容,所以源对象改变的时候,拷贝的对象也会随之改变。那么怎么进行深拷贝呢?
使用在源对象中就进行深拷贝的操作
doc.mImages = (ArrayList<String>) this.mImages.clone();//这样就是深拷贝
使用这个之后我们可以再来看下打印的结果
使用完之后我们就会发现,这两个对象之间没有任何联系,是单独的两个对象,这也就是深拷贝的结果。