我的博客java
原型模式是一個建立型的模式。多用於建立複雜的或者構造耗時的實例,由於這種狀況下,複製一個已經存在的實例,可以使程序運行更高效。函數
用原型實例指定建立對象的種類,並經過複製這些原型建立新的對象。this
類初始化須要消耗很是多的資源code
經過new產生一個對象須要很是繁瑣的數據準備或訪問權限對象
一個對象須要提供給其它對象訪問,並且各個調用者可能都須要修改值接口
經過實現Cloneable接口的原型模式在調用clone函數構造實例時,並不必定比經過new操做速度快,只有當經過new構造函數對象較爲耗時或成本較高時,經過clone方法纔可以得到效率上的提高。圖片
以簡單的文檔拷貝爲例演示簡單的原型模式。資源
先來演示淺拷貝文檔
文檔定義
public class Document implements Cloneable { private String mText; private ArrayList<String> mImages = new ArrayList<>(); public String getmText() { return mText; } public void setmText(String mText) { this.mText = mText; } public List<String> getmImages() { return mImages; } public void addImage(String image) { mImages.add(image); } public void showDocument() { System.out.println(this); } @Override protected Object clone() throws CloneNotSupportedException { Document doc = (Document) super.clone(); doc.mText = this.mText; doc.mImages = this.mImages; return doc; } @Override public String toString() { return "Document [mText=" + mText + ", mImages=" + mImages + "]"; } }
調用
public static void main(String[] args) { Document doc1 = new Document(); doc1.setmText("文檔1"); doc1.addImage("圖片1"); doc1.showDocument(); Document doc2; try { doc2 = (Document) doc1.clone(); doc2.setmText("文檔2"); doc2.addImage("圖片2"); doc2.showDocument(); doc.showDocument(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } }
建立文檔1,而後顯示文檔1的內容。而後拷貝了文檔1,修改了文檔1的內容,而後依次顯示文檔2,文檔1
輸出結果
Document [mText=文檔1, mImages=[圖片1]] Document [mText=文檔2, mImages=[圖片1, 圖片2]] Document [mText=文檔1, mImages=[圖片1, 圖片2]]
能夠看到,修改拷貝後的文檔2的Text,文檔1沒有受影響,可是修改文檔2的Images,文檔1也被修改了。
下面演示深拷貝
只須要修改clone方法
@SuppressWarnings("unchecked") @Override protected Object clone() throws CloneNotSupportedException { Document doc = (Document) super.clone(); doc.mText = this.mText; //doc.mImages = this.mImages; doc.mImages = (ArrayList<String>) this.mImages.clone(); return doc; }
再次運行後的輸出結果:
Document [mText=文檔1, mImages=[圖片1]] Document [mText=文檔2, mImages=[圖片1, 圖片2]] Document [mText=文檔1, mImages=[圖片1]]
修改文檔2的Images並無影響到文檔1。
原型模式本質上就是對象拷貝,容易出現的問題是深拷貝、淺拷貝。使用原型模式能夠解決構建複雜對象的資源消耗問題,可以在某些場景下提高建立對象的效率。還有一個重要用途是保護性拷貝,也就是某個對象對外多是隻讀的,爲了防止外部對這個只讀對象修改,能夠經過返回一個對象拷貝的形式來實現只讀的限制。