原型模式
原型二字表明了该模式应该有一个样版实例,用户从这个样板对象中复制出一个内部属性一致的对象,被复制的实例就是我们所称的"原型"。
定义:用原型实例指定创建对象的种类,并通过拷贝这此原型创建新的对象(深拷贝和浅拷贝)
浅拷贝
package com.zc.test;
import java.util.ArrayList;
public class DeepCopy implements Cloneable {
private int num;
private ArrayList<Integer> mArray = new ArrayList<Integer>();
@Override
protected Object clone() throws CloneNotSupportedException {
try {
DeepCopy mDeepCopy = (DeepCopy) super.clone();
mDeepCopy.num = this.num;
// 这个等于号:一个对象的引用等于别外一个对象,一个对象的改变,别一个对象跟会跟着改变
//标记1处
mDeepCopy.mArray = this.mArray;
return mDeepCopy;
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public void setNum(int num) {
this.num = num;
}
public int getNum() {
return num;
}
public void addNum(int num) {
mArray.add(num);
}
public void showArray() {
for (Integer array : mArray) {
System.out.println(array);
}
}
public void showAllInfo() {
System.out.println(getNum());
showArray();
}
}
调用:
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
// TODO Auto-generated method stub
DeepCopy mDeepCopy1 = new DeepCopy();
mDeepCopy1.setNum(1);
mDeepCopy1.addNum(2);
mDeepCopy1.addNum(3);
mDeepCopy1.showAllInfo();
DeepCopy mDeepCopy2 = (DeepCopy) mDeepCopy1.clone();
mDeepCopy2.setNum(2);
mDeepCopy2.showAllInfo();
mDeepCopy1.showAllInfo();
}
}
结果:
1
2
3
分隔线
2
2
3
分隔线
1
2
3
分隔线
但是,假如这样调用:
DeepCopy mDeepCopy1 = new DeepCopy();
mDeepCopy1.setNum(1);
mDeepCopy1.addNum(2);
mDeepCopy1.addNum(3);
mDeepCopy1.showAllInfo();
DeepCopy mDeepCopy2 = (DeepCopy) mDeepCopy1.clone();
mDeepCopy2.setNum(2);
mDeepCopy2.showAllInfo();
mDeepCopy1.showAllInfo();
结果:
1
2
3
分隔线
2
2
3
4
分隔线
1
2
3
4
分隔线
上述就是浅拷贝
深拷贝
就是将上面代码的标记1处,改成
mDeepCopy.mArray = (ArrayList<Integer>) this.mArray.clone();
结果就变成了:
1
2
3
分隔线
2
2
3
4
分隔线
1
2
3
分隔线
结论:
1、类初始化需要消化非常多的资源,这个资源包括数据,硬件资源等,通过原型拷贝避免这些消耗。
2、通过new产生一个对象需要非常繁的数据准备或访问权限,这时可以使用原型模式
3、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。
注意:通过实现Cloneable接口的原型模式在调用 clone函数构造实例时并不一定比通过new操作速度快,当只有通过new构造对象有时或者成本较高时,通过clone方法才能获取效率上的提升。