在有些系統中,存在大量相同或相似對象的創建問題,如果用傳統的構造函數來創建對象,會比較複雜且耗時耗資源,用原型模式生成對象就很高效,就像孫悟空拔下猴毛輕輕一吹就變出很多孫悟空一樣簡單。
原型模式的定義與特點
原型(Prototype)模式的定義如下:用一個已經創建的實例作爲原型,通過複製該原型對象來創建一個和原型相同或相似的新對象。在這裏,原型實例指定了要創建的對象的種類。用這種方式創建對象非常高效,根本無須知道對象創建的細節。例如,Windows 操作系統的安裝通常較耗時,如果複製就快了很多。在生活中複製的例子非常多,這裏不一一列舉了。
原型模式的優點:
- Java 自帶的原型模式基於內存二進制流的複製,在性能上比直接 new 一個對象更加優良。
- 可以使用深克隆方式保存對象的狀態,使用原型模式將對象複製一份,並將其狀態保存起來,簡化了創建對象的過程,以便在需要的時候使用(例如恢復到歷史某一狀態),可輔助實現撤銷操作。
原型模式的缺點:
- 需要爲每一個類都配置一個 clone 方法
- clone 方法位於類的內部,當對已有類進行改造的時候,需要修改代碼,違背了開閉原則。
- 當實現深克隆時,需要編寫較爲複雜的代碼,而且當對象之間存在多重嵌套引用時,爲了實現深克隆,每一層對象對應的類都必須支持深克隆,實現起來會比較麻煩。因此,深克隆、淺克隆需要運用得當。
原型模式的結構與實現
由於 Java 提供了對象的 clone() 方法,所以用 Java 實現原型模式很簡單。
1. 模式的結構
原型模式包含以下主要角色。
- 抽象原型類:規定了具體原型對象必須實現的接口。
- 具體原型類:實現抽象原型類的 clone() 方法,它是可被複制的對象。
- 訪問類:使用具體原型類中的 clone() 方法來複制新的對象。
2. 模式的實現
原型模式的克隆分爲淺克隆和深克隆。
- 淺克隆:創建一個新對象,新對象的屬性和原來對象完全相同,對於非基本類型屬性,仍指向原有屬性所指向的對象的內存地址。
- 深克隆:創建一個新對象,屬性中引用的其他對象也會被克隆,不再指向原有對象地址。
Java 中的 Object 類提供了淺克隆的 clone() 方法,具體原型類只要實現 Cloneable 接口就可實現對象的淺克隆,這裏的 Cloneable 接口就是抽象原型類。其代碼如下:
//具體原型類
class Realizetype implements Cloneable {
Realizetype() {
System.out.println("具體原型創建成功!");
}
public Object clone() throws CloneNotSupportedException {
System.out.println("具體原型複製成功!");
return (Realizetype) super.clone();
}
}
//原型模式的測試類
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Realizetype obj1 = new Realizetype();
Realizetype obj2 = (Realizetype) obj1.clone();
System.out.println("obj1==obj2?" + (obj1 == obj2));
}
}
程序的運行結果如下:
具體原型創建成功!
具體原型複製成功!
obj1==obj2?false