建立型模式 – 原型模式
定義
原型模式(Prototype Pattern):使用原型執行個體指定建立對象的種類,并且通過拷貝這些原型建立新的對象。原型模式是一種對象建立型模式。
原型模式的工作原理很簡單:将一個原型對象傳給那個要發動建立的對象,這個要發動建立的對象通過請求原型對象拷貝自己來實作建立過程。
需要注意的是通過克隆方法所建立的對象是全新的對象,它們在記憶體中擁有新的位址,通常對克隆所産生的對象進行修改對原型對象不會造成任何影響,每一個克隆對象都是互相獨立的。通過不同的方式修改可以得到一系列相似但不完全相同的對象。
角色
Prototype(抽象原型類)
它是聲明克隆方法的接口,是所有具體原型類的公共父類,可以是抽象類也可以是接口,甚至還可以是具體實作類。
ConcretePrototype(具體原型類)
它實作在抽象原型類中聲明的克隆方法,在克隆方法中傳回自己的一個克隆對象。
Client(客戶類)
讓一個原型對象克隆自身進而建立一個新的對象,在客戶類中隻需要直接執行個體化或通過工廠方法等方式建立一個原型對象,再通過調用該對象的克隆方法即可得到多個相同的對象。由于客戶類針對抽象原型類Prototype程式設計,是以使用者可以根據需要選擇具體原型類,系統具有較好的可擴充性,增加或更換具體原型類都很友善。
通用實作方法
class ConcretePrototype implements Prototype{
private String attr; //成員屬性
public void setAttr(String attr){
this.attr = attr;
}
public String getAttr(){
return this.attr;
}
public Prototype clone() //克隆方法{
Prototype prototype = new ConcretePrototype(); //建立新對象
prototype.setAttr(this.attr);
return prototype;
}
}
Java語言中的clone()方法
1. 對任何對象x,都有x.clone() != x,即克隆對象與原型對象不是同一個對象;
2. 對任何對象x,都有x.clone().getClass() == x.getClass(),即克隆對象與原型對象的類型一樣;
3. 如果對象x的equals()方法定義恰當,那麼x.clone().equals(x)應該成立。
為了擷取對象的一份拷貝,我們可以直接利用Object類的clone()方法,具體步驟如下:
(1) 在派生類中覆寫基類的clone()方法,并聲明為public;
(2) 在派生類的clone()方法中,調用super.clone();
(3) 派生類需實作Cloneable接口。
總結
優點
(1) 當建立新的對象執行個體較為複雜時,使用原型模式可以簡化對象的建立過程,通過複制一個已有執行個體可以提高新執行個體的建立效率。
(2) 擴充性較好,由于在原型模式中提供了抽象原型類,在用戶端可以針對抽象原型類進行程式設計,而将具體原型類寫在配置檔案中,增加或減少産品類對原有系統都沒有任何影響。
(3) 原型模式提供了簡化的建立結構,工廠方法模式常常需要有一個與産品類等級結構相同的工廠等級結構,而原型模式就不需要這樣,原型模式中産品的複制是通過封裝在原型類中的克隆方法實作的,無須專門的工廠類來建立産品。
(4) 可以使用深克隆的方式儲存對象的狀态,使用原型模式将對象複制一份并将其狀态儲存起來,以便在需要的時候使用(如恢複到某一曆史狀态),可輔助實作撤銷操作。
缺點
(1) 需要為每一個類配備一個克隆方法,而且該克隆方法位于一個類的内部,當對已有的類進行改造時,需要修改源代碼,違背了“開閉原則”。
(2) 在實作深克隆時需要編寫較為複雜的代碼,而且當對象之間存在多重的嵌套引用時,為了實作深克隆,每一層對象對應的類都必須支援深克隆,實作起來可能會比較麻煩。