java設計模式--原型模式
阿新 • • 發佈:2019-02-06
原型模式
定義:
用原型例項指定建立物件的種類, 並且通過拷貝這些原型建立新的物件。
原型模式的核心是一個clone方法, 通過該方法進行物件的拷貝, Java 提供了一個Cloneable介面來標示這個物件是可拷貝的,在JVM中具有這個標記的物件才有可能被拷貝。
比如:比如批量傳送郵件,郵件模板是一樣的,傳送給不同的人內容不同,那麼就可以把模板 clone 給不同的傳送者,傳送者修改一下內容模板內容,然後就傳送。就是生產一個物件不是從new開始的,而是從已經存在的一個物件直接拷貝過來,然後修改修改就好了。
優點:
1、原型模式是在記憶體中二進位制流的拷貝,要比直接new效能好很多。如果在一個迴圈體內建立大量物件,原型模式能體現出他的優點。
2、由於是二進位制的拷貝,所有建構函式不會被執行。這也是優點,也是缺點,在實際應用中要考慮。
使用場景:
一個物件要給其它物件訪問,並且其它物件可能會修改這個物件。可以考慮使用原型模式。
注意事項:
1、建構函式不會被執行
淺拷貝
Object類提供的方法clone只是拷貝本物件,其物件內部的陣列、引用物件等都不拷貝, 還是指向原生物件的內部元素地址, 這種拷貝就叫做淺拷貝。
注:String 是不可變的,處理機制比較特殊,通過字串池在需要的時候才在記憶體中建立新的字串。
深拷貝
物件內部的陣列、引用物件等要手動拷貝。示例程式碼:修改上面的clone() 方法如下:
還有一點要注意的是:想要clone 的屬性,不能是final的。
定義:
用原型例項指定建立物件的種類, 並且通過拷貝這些原型建立新的物件。
原型模式的核心是一個clone方法, 通過該方法進行物件的拷貝, Java 提供了一個Cloneable介面來標示這個物件是可拷貝的,在JVM中具有這個標記的物件才有可能被拷貝。
比如:比如批量傳送郵件,郵件模板是一樣的,傳送給不同的人內容不同,那麼就可以把模板 clone 給不同的傳送者,傳送者修改一下內容模板內容,然後就傳送。就是生產一個物件不是從new開始的,而是從已經存在的一個物件直接拷貝過來,然後修改修改就好了。
優點:
1、原型模式是在記憶體中二進位制流的拷貝,要比直接new效能好很多。如果在一個迴圈體內建立大量物件,原型模式能體現出他的優點。
2、由於是二進位制的拷貝,所有建構函式不會被執行。這也是優點,也是缺點,在實際應用中要考慮。
使用場景:
一個物件要給其它物件訪問,並且其它物件可能會修改這個物件。可以考慮使用原型模式。
注意事項:
1、建構函式不會被執行
淺拷貝
Object類提供的方法clone只是拷貝本物件,其物件內部的陣列、引用物件等都不拷貝, 還是指向原生物件的內部元素地址, 這種拷貝就叫做淺拷貝。
注:String 是不可變的,處理機制比較特殊,通過字串池在需要的時候才在記憶體中建立新的字串。
示例程式碼:
說明: 執行結果打印出 [A, B] prototype,clone兩個物件引用的是同一樣ArrayList。public class Prototype implements Cloneable { private List<String> list = new ArrayList<>(); @Override protected Object clone() throws CloneNotSupportedException { //淺拷貝 return super.clone(); } public void add(String str) { list.add(str); } public List<String> getList() { return list; } /** * 測試程式碼 * @param args * @throws Exception */ public static void main(String[] args) throws Exception{ Prototype prototype = new Prototype(); prototype.add("A"); Prototype clone = (Prototype)prototype.clone(); clone.add("B"); //此處打出 A , B System.out.println(prototype.getList()); //此處打出 A , B System.out.println(clone.getList()); } }
深拷貝
物件內部的陣列、引用物件等要手動拷貝。示例程式碼:修改上面的clone() 方法如下:
修改後就正常了@Override protected Object clone() throws CloneNotSupportedException { //深拷貝 Prototype clone = (Prototype)super.clone(); clone.list = (ArrayList)((ArrayList)this.list).clone(); return clone; }
還有一點要注意的是:想要clone 的屬性,不能是final的。