本文參考自《設計模式之禪》,《Java與模式》
一、通過給出一個原型對象來指明所要建立的對象的類型。
二、Java中半支援
1.Ojbect類提供一個clone方法。
2.Java必須實現Cloneable來顯式表明Javabean支援複製。
3.如果不實現Cloneable介面而直接使用,會拋出java.lang.CloneNotSupportedException。
4.預設的實現是淺拷貝,需要重寫clone方法。
三、Code
package com.jue.dp;public class TV implements Cloneable {private int price;private Box box;public TV(Box b, int price) {this.box = b;this.price = price;System.out.println("TV()");}public Box getBox() {return box;}public void setBox(Box box) {this.box = box;}void display() {System.out.println(box.name + " , " + price);}@Overrideprotected TV clone() throws CloneNotSupportedException {TV temp = (TV) super.clone();temp.box = box.clone();return temp;}}
package com.jue.dp;public class Box implements Cloneable {public String name = "default";@Overrideprotected Box clone() throws CloneNotSupportedException {return (Box) super.clone();}}
package com.jue.dp;public class MainClass {public static void main(String[] args) throws CloneNotSupportedException {Box b1 = new Box();TV t1 = new TV(b1, 100);t1.display();System.out.println("------------------------");TV t2 = t1.clone();t2.display();System.out.println("------------------------");b1.name = "changed";t1.display();t2.display();}}
四、優點
1.原型模式是在記憶體中二進位流的拷貝,比直接new一個對象效能要好很多。
2.直接在記憶體中拷貝,建構函式不會執行。
3.能夠擷取一個即時狀態的值。
五、缺點
1.構造器不會執行。
六、注意點
1.Object的clone如果只是調用super.clone,複合類型只是淺拷貝(對象中的數組對象,其他綜合物件,但是String是深拷貝)。
2.Clone與final常量有衝突,如下有編譯錯誤。
package com.jue.dp;import java.util.ArrayList;public class Things implements Cloneable {private final ArrayList<String> arraylist = new ArrayList<String>();@Overrideprotected Object clone() throws CloneNotSupportedException {Things t = (Things) super.clone();t.arraylist = (ArrayList<String>) this.arraylist.clone();return super.clone();}}
七、使用情境
1.類的初始化需要較多資源。
2.需要記錄一個狀態的對象的值。
3.使用new需要較為繁瑣的準備和存取權限使用受限。