使程序運行更高效 —— 原型模式
1. 原型模式介紹
原型模式是一個創(chuàng)建型的模式陨溅。原型二字表明了該模式應(yīng)該有一個樣板實例实柠,用戶從這個樣板對象中復(fù)制出一個內(nèi)部屬性一致的對象橱脸,這個過程也就是我們俗稱的“克隆”抒和。被復(fù)制的實例就是我們所稱的“原型”膳沽,這個原型是可定制的汗菜。原型模式多用于創(chuàng)建復(fù)雜的或者構(gòu)造耗時的實例,因為這種情況下挑社,復(fù)制一個已經(jīng)存在的實例可以使程序運行更高效陨界。
2. 原型模式的定義
用原型實例指定創(chuàng)建對象的種類,并通過拷貝這些原型創(chuàng)建新的對象痛阻。
3. 原型模式的使用場景
(1) 類初始化需要消耗非常多的資源菌瘪,這些資源包括數(shù)據(jù)、硬件資源等阱当,通過原型拷貝避免這些消耗俏扩;
(2) 通過 new 產(chǎn)生一個對象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問權(quán)限缀皱,這時可以使用原型模式;
(3) 一個對象需要提供給其他對象訪問动猬,而且各個調(diào)用者可能都需要修改其值時啤斗,可以考慮使用原型模式拷貝多個對象供調(diào)用者使用,即保護(hù)性拷貝赁咙。
需要注意的是钮莲,通過實現(xiàn) Cloneable 接口的原型模式在調(diào)用 clone 函數(shù)構(gòu)造實例時并不一定比通過 new 操作速度快,只有當(dāng)通過 new 構(gòu)造對象較為耗時或者說成本較高時彼水,通過 clone 方法才能夠獲得效率上的提升崔拥。因此,在使用 Cloneable 時需要考慮構(gòu)建對象的成本以及做一些效率上的測試凤覆。
4. 原型模式的簡單實現(xiàn)
簡單的實例:
import java.util.ArrayList;
/**
* Created by toby on 18-3-16.
*/
public class WordDocument implements Cloneable {
private String text;
private ArrayList<String> images = new ArrayList<>();
@Override
@SuppressWarnings("unchecked")
protected WordDocument clone() {
try {
WordDocument document = (WordDocument) super.clone();
document.text = this.text;
// document.images = this.images;// 這是淺拷貝
document.images = (ArrayList<String>) this.images.clone(); // 對于引用型字段實現(xiàn)深拷貝
return document;
} catch (Exception e){
}
return null;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public ArrayList<String> getImages() {
return images;
}
public String getImage(int index) {
if (index < 0 && index >= images.size()) {
return "";
}
return this.images.get(index);
}
public void setImages(ArrayList<String> images) {
this.images = images;
}
public void setImage(String image) {
this.images.add(image);
}
public void showDocument() {
System.out.println("-------------- Word Content Start ---------------");
System.out.println("Text: " + text);
System.out.println("Images List: ");
for (String imgName : images) {
System.out.println("image name: " + imgName);
}
System.out.println("-------------- Word Content End -----------------");
}
}
對實例的測試:
public class LearnJava {
public static void main(String[] args) {
WordDocument originDoc = new WordDocument();
originDoc.setText("This is a test document.");
originDoc.setImage("image 01");
originDoc.setImage("image 02");
originDoc.setImage("image 03");
originDoc.showDocument();
WordDocument document2 = originDoc.clone();
document2.showDocument();
document2.setText("This is a clone document.");
document2.setImage("new image 04");
document2.showDocument();
originDoc.showDocument();
}
}
優(yōu)點與缺點
優(yōu)點:
原型模式是在內(nèi)存中二進(jìn)制流的拷貝链瓦,要比直接 new 一個對象性能好很多,特別是要在一個循環(huán)體內(nèi)產(chǎn)生大量的對象時盯桦,原型模式可以更好地體現(xiàn)其優(yōu)點慈俯。
缺點:
這既是它的優(yōu)點也是缺點,直接在內(nèi)存中拷貝拥峦,構(gòu)造函數(shù)是不會執(zhí)行的贴膘,在實際開發(fā)當(dāng)中應(yīng)該注意這個潛在的問題。優(yōu)點是減少了約束略号,缺點也是減少了約束刑峡,需要大家在實際應(yīng)用時考慮。