原型模式
原型二字表明了該模式應(yīng)該有一個(gè)樣版實(shí)例,用戶(hù)從這個(gè)樣板對(duì)象中復(fù)制出一個(gè)內(nèi)部屬性一致的對(duì)象,被復(fù)制的實(shí)例就是我們所稱(chēng)的"原型"。
定義:用原型實(shí)例指定創(chuàng)建對(duì)象的種類(lèi),并通過(guò)拷貝這此原型創(chuàng)建新的對(duì)象(深拷貝和淺拷貝)
淺拷貝
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;
// 這個(gè)等于號(hào):一個(gè)對(duì)象的引用等于別外一個(gè)對(duì)象,一個(gè)對(duì)象的改變,別一個(gè)對(duì)象跟會(huì)跟著改變
//標(biāo)記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();
}
}
調(diào)用:
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();
}
}
結(jié)果:
1
2
3
分隔線
2
2
3
分隔線
1
2
3
分隔線
但是,假如這樣調(diào)用:
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();
結(jié)果:
1
2
3
分隔線
2
2
3
4
分隔線
1
2
3
4
分隔線
上述就是淺拷貝
深拷貝
就是將上面代碼的標(biāo)記1處,改成
mDeepCopy.mArray = (ArrayList<Integer>) this.mArray.clone();
結(jié)果就變成了:
1
2
3
分隔線
2
2
3
4
分隔線
1
2
3
分隔線
結(jié)論:
1、類(lèi)初始化需要消化非常多的資源,這個(gè)資源包括數(shù)據(jù),硬件資源等,通過(guò)原型拷貝避免這些消耗。
2、通過(guò)new產(chǎn)生一個(gè)對(duì)象需要非常繁的數(shù)據(jù)準(zhǔn)備或訪問(wèn)權(quán)限,這時(shí)可以使用原型模式
3、一個(gè)對(duì)象需要提供給其他對(duì)象訪問(wèn),而且各個(gè)調(diào)用者可能都需要修改其值時(shí),可以考慮使用原型模式拷貝多個(gè)對(duì)象供調(diào)用者使用,即保護(hù)性拷貝。
注意:通過(guò)實(shí)現(xiàn)Cloneable接口的原型模式在調(diào)用 clone函數(shù)構(gòu)造實(shí)例時(shí)并不一定比通過(guò)new操作速度快,當(dāng)只有通過(guò)new構(gòu)造對(duì)象有時(shí)或者成本較高時(shí),通過(guò)clone方法才能獲取效率上的提升。