原型模式是一個(gè)創(chuàng)造型的模式勇婴。表明了該模式需要有一個(gè)樣板實(shí)例,用戶從這個(gè)樣板中復(fù)制出一個(gè)內(nèi)部屬性一致的對(duì)象。
定義
用原型實(shí)例指定創(chuàng)建對(duì)象的種類详羡,并通過復(fù)制這些原型創(chuàng)建新的對(duì)象。
使用場(chǎng)景
- 類初始化需要消耗非常多的資源嘿悬,這個(gè)資源包括數(shù)據(jù)实柠,硬件資源等,通過原型復(fù)制避免這些消耗善涨。
- 通過new產(chǎn)生一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問權(quán)限窒盐。
- 一個(gè)對(duì)象需要提供給其他對(duì)象訪問草则,而且各個(gè)調(diào)用者可能都需要修改其值,可以使用原型模式復(fù)制多個(gè)對(duì)象供使用者使用蟹漓,即保護(hù)性拷貝炕横。
示例
public class WordDocument {
private String text;
private ArrayList<String> list = new ArrayList<String>();
public WordDocument() {
System.out.println("構(gòu)造方法");
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public ArrayList<String> getList() {
return list;
}
public void setList(ArrayList<String> list) {
this.list = list;
}
public void addString(String string) {
list.add(string);
}
@Override
protected WordDocument clone() {
try {
WordDocument nwd = (WordDocument) super.clone();
nwd.setText(this.text);
nwd.setList(this.list);
return nwd;
} catch (CloneNotSupportedException e) {
}
return null;
}
}
在java中我們可以利用重寫clone方法來實(shí)現(xiàn)原型模式,需要注意的是使用clone方法構(gòu)建的新對(duì)象葡粒,并不會(huì)調(diào)用構(gòu)造方法份殿。如果需要在構(gòu)造方法中進(jìn)行初始化,則不用調(diào)用super.clone()實(shí)現(xiàn)原型模式嗽交。
淺拷貝和深拷貝
在上面的那個(gè)例子中卿嘲,就是淺拷貝,只是拷貝了text而并沒有拷貝集合夫壁。兩個(gè)對(duì)象的list依然指向同一個(gè)ArrayList集合拾枣。這樣會(huì)導(dǎo)致當(dāng)修改拷貝的對(duì)象的時(shí)候,也會(huì)修改樣板對(duì)象盒让,這樣便失去了保護(hù)性拷貝的作用梅肤。所以需要修改clone方法。
@SuppressWarnings("unchecked")
@Override
protected WordDocument clone() {
try {
WordDocument nwd = (WordDocument) super.clone();
nwd.setText(this.text);
nwd.setList((ArrayList<String>) this.list.clone());
return nwd;
} catch (CloneNotSupportedException e) {
}
return null;
}
在創(chuàng)建拷貝的時(shí)候糯彬,對(duì)內(nèi)部的對(duì)象同樣需要調(diào)用內(nèi)部對(duì)象的clone方法凭语,保證在修改拷貝對(duì)象是不會(huì)影響樣板對(duì)象。