1.原型模式的介紹
原型模式是一個創建型的模式,該模式應該有一個樣板實例,用戶從這個樣板對象中複製出一個內部屬性
一致的對象,這個過程俗稱克隆,被複制的實例就是所稱的原型,原型可定製。原型模式多用於創建複雜
的或者構造耗時的實例,因爲這種情況下,複製一個已經存在的實例可使程序運行更高效。
2.定義
用原型實例指定創建對象的種類,並通過複製這些原型創建新的對象。
3.使用場景:
1>.類的初始化需要消耗非常多的資源,這個資源包括數據,硬件資源等。原型複製可以避免這些消耗。
2>.通過new產生一個對象需要非常繁瑣的數據準備或訪問權限,這時可以使用原型複製。
3>.一個對象需要提供給其它對象訪問,而且各個調用者可能都需要修改其值時,可以考慮用原型模式復
制多個對象供調用者使用,即保護性拷貝。
注意:通過實現Cloneable接口的原型模式在調用clone函數構造實例時並不一定比通過new操作速度快,
只有當通過new構造對象較爲耗時或者說成本較高時,通過clone方法才能夠獲得效率上的提升。因此,
在使用Cloneable時需要考慮構建對象的成本以及做一些效率上的測試。當然原型模式也不一定非要實現
Cloneable接口,也有其它的實現方式。
4.總結
原型模式本質上就是對象拷貝,與C++中拷貝構造函數有些類似,它們之間容易出現的問題也都是深拷貝
,淺拷貝。使用原型模式可以解決構建複雜對象的資源消耗問題,能夠在某些場景下提升創建對象的效率
。還有一個重要的用途就是保護性拷貝,也就是某個對象對外可能是隻讀的,爲了防止外部對這個只讀對
象修改,通常可以通過返回一個對象拷貝的形式實現只讀的限制。
優點:原型模式是在內存中二進制流的拷貝,要比直接new一個對象性能好很多,特別是要在一個循環體
內產生大量的對象時,原型模式可以更好地體現其優點。
缺點:即是優點也是缺點,直接在內存中拷貝,構造函數是不會執行的,在實際開發當中應該注意這個潛
在的問題。優點就是減少了約束,缺點也是減少了約束。
5.簡單實例
public class WrodDocument implements Cloneable {
private String mText;
private ArrayList<String> mImages = new ArrayList<>();
public WrodDocument() {
System.out.println("------------------WordDocument構造函數----------------");
}
@Override
protected WrodDocument clone() {
try {
WrodDocument doc = null;
doc = (WrodDocument) super.clone();
doc.mText = this.mText;
doc.mImages = (ArrayList<String>) this.mImages.clone();
return doc;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
public String getmText() {
return mText;
}
public void setmText(String mText) {
this.mText = mText;
}
public ArrayList<String> getmImages() {
return mImages;
}
public void addImages(String img) {
this.mImages.add(img);
}
public void showDocument(){
System.out.println("---------------Word Content Start---------------");
System.out.println("Text:"+mText);
System.out.println("Images List:");
for (String imgName:mImages){
System.out.println("image name:"+imgName);
}
System.out.println("---------------Word Content End------------------");
}
}
public class Client {
public static void main(String[] args) {
WrodDocument originDoc=new WrodDocument();
originDoc.setmText("這是一篇文檔");
originDoc.addImages("圖片1");
originDoc.addImages("圖片2");
originDoc.addImages("圖片3");
originDoc.showDocument();
WrodDocument doc2=originDoc.clone();
doc2.showDocument();
doc2.setmText("這是修改過的Doc2文本");
originDoc.setmText("測試修改");
originDoc.addImages("測試");
doc2.showDocument();
originDoc.showDocument();
}
}