1. 程式人生 > >java設計模式--原型模式

java設計模式--原型模式

原型模式
定義:
用原型例項指定建立物件的種類, 並且通過拷貝這些原型建立新的物件。 

原型模式的核心是一個clone方法, 通過該方法進行物件的拷貝, Java 提供了一個Cloneable介面來標示這個物件是可拷貝的,在JVM中具有這個標記的物件才有可能被拷貝。 
比如:比如批量傳送郵件,郵件模板是一樣的,傳送給不同的人內容不同,那麼就可以把模板 clone 給不同的傳送者,傳送者修改一下內容模板內容,然後就傳送。就是生產一個物件不是從new開始的,而是從已經存在的一個物件直接拷貝過來,然後修改修改就好了。

優點:
1、原型模式是在記憶體中二進位制流的拷貝,要比直接new效能好很多。如果在一個迴圈體內建立大量物件,原型模式能體現出他的優點。
2、由於是二進位制的拷貝,所有建構函式不會被執行。這也是優點,也是缺點,在實際應用中要考慮。

使用場景:
一個物件要給其它物件訪問,並且其它物件可能會修改這個物件。可以考慮使用原型模式。

注意事項:
1、建構函式不會被執行

淺拷貝
Object類提供的方法clone只是拷貝本物件,其物件內部的陣列、引用物件等都不拷貝, 還是指向原生物件的內部元素地址, 這種拷貝就叫做淺拷貝。
注:String 是不可變的,處理機制比較特殊,通過字串池在需要的時候才在記憶體中建立新的字串。

示例程式碼:

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());
    }
}
說明: 執行結果打印出 [A, B]   prototype,clone兩個物件引用的是同一樣ArrayList。

深拷貝
物件內部的陣列、引用物件等要手動拷貝。示例程式碼:修改上面的clone() 方法如下:
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //深拷貝
        Prototype clone = (Prototype)super.clone();
        clone.list = (ArrayList)((ArrayList)this.list).clone();
        return clone;
    }
修改後就正常了

還有一點要注意的是:想要clone 的屬性,不能是final的。