原型模式的定義:
用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象。
使用場景:
1.類的初始化需要非常多資源時(數據硬件資源),通過原型拷貝避免這些消耗
2.通過new一個對象需要非常繁瑣的數據準備和訪問權限時
3.一個對象要供給多個對象訪問,而且多個對象都肯要修改其值時,可以通過原型模式拷貝多個對象共調用者使用
原型模式多用於創建複雜或者構造耗時的實例,這時複製一個已有的實例使得程序運行更高效。
UML類圖
原型模式的簡單實現:
package prototype;
import java.util.ArrayList;
//利用java提供的cloneable接口
public class WordDocument implements Cloneable{
//文本
private String mText;
//圖片
private ArrayList<String> mImage = new ArrayList<>();
public WordDocument() {
super();
System.out.println("———————WordDocument的構造函數———————————");
}
@SuppressWarnings("unchecked")
@Override
protected Object clone(){
// TODO Auto-generated method stub
WordDocument doc = null;
try {
doc = (WordDocument) super.clone();
doc.mText = this.mText;
//淺拷貝 ,這樣的備備份是對原有實例的引用,修改備份會影響原有實例
//doc.mImage = this.mImage;
//深拷貝,對引用類型採用拷貝的形式拷貝,這樣得到的備份是與原來的備份無關的,即修改備份不影響原有實例。
//進行修改後的代碼
doc.mImage = ((ArrayList<String>) this.mImage.clone());
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return doc;
}
public String getmText() {
return mText;
}
public void setmText(String mText) {
this.mText = mText;
}
public void addmImage(String mImage) {
this.mImage.add(mImage);
}
@Override
public String toString() {
return "WordDocument [mText=" + mText + ", mImage=" + mImage + "]";
}
}
package prototype;
public class Client {
public static void main(String[] args) {
WordDocument originDoc = new WordDocument();
originDoc.setmText("this is the first text");
originDoc.addmImage("this is a");
originDoc.addmImage("this is b");
originDoc.addmImage("this is c");
System.out.println(originDoc.toString());
// 以原始文檔爲原型拷貝一份副本
WordDocument doc2 = (WordDocument) originDoc.clone();
// 發現沒有再次執行構造函數
doc2.setmText("this is the second text");
System.out.println(originDoc.toString());
// 修改text信息發現原內容originDoc的信息不變--》說明其是深拷貝
// 那麼修改imageAdd內容呢?
doc2.addmImage("this is d");
// 發現內容改變,說明這時的拷貝是淺拷貝,需要將image的引用進行拷貝才能達到深拷貝的效果
System.out.println(originDoc.toString());
}
}
使用原型設計模式的注意點:
1.需要注意的是使用clone拷貝對象時不會執行構造函數
2.深淺拷貝問題,儘量使用深拷貝避免對原有實例的影響