用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象
Prototype模式允許一個對象再創建另外一個可定製的對象,根本無需知道任何如何創建的細節,工作原理是:通過將一個原型對象傳給那個要發動創建的對象,這個要發動創建的對象通過請求原型對象拷貝它們自己來實施創建
適用性:
1.當一個系統應該獨立於它的產品創建,構成和表示時
2.當要實例化的類是在運行時刻指定時,例如,通過動態加載
3.爲了避免創建一個與產品類層次平行的工廠層次時。
4.當一個類的實例只能有幾個不同狀態組合中的一種時
UML:
原型模式主要用於對象的複製,它的核心是就是類圖中的原型類Prototype。Prototype類需要具備以下兩個條件:
實現Cloneable接口。
在java語言有一個Cloneable接口,它的作用只有一個,就是在運行時通知虛擬機可以安全地在實現了此接口的類上使用clone方法。在java虛擬機中,只有實現了這個接口的類纔可以被拷貝,否則在運行時會拋出CloneNotSupportedException異常。
重寫Object類中的clone方法。
Java中,所有類的父類都是Object類,Object類中有一個clone方法,作用是返回對象的一個拷貝,但是其作用域protected類型的,一般的類無法調用,因此,Prototype類需要將clone方法的作用域修改爲public類型。
原型模式是一種比較簡單的模式,也非常容易理解,實現一個接口,重寫一個方法即完成了原型模式。在實際應用中,原型模式很少單獨出現。經常與其他模式混用,他的原型類Prototype也常用抽象類來替代。
參與者
1.Prototype
聲明一個克隆自身的接口
2.ConcretePrototype
實現一個克隆自身的操作
3.Client
讓一個原型克隆自身從而創建一個新的對象
一個簡單的例子:
Prototype
public class Prototype implements Cloneable{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public Object clone(){
try{
return super.clone();
}catch (Exception e){
e.printStackTrace();
return null;
}
}
ConcretePrototype
public class ConcretePrototype extends Prototype{
public ConcretePrototype(String name){
setName(name);
}
}
Client
public class Test{
public static void main (String[] args){
Prototype pro = new ConcretePrototype("prototype");
Prototype pro_2 = (Prototype)pro.clone();
System.out.println(pro.getName());
System.out.println(pro_2.getName());
}
result:
prototype
prototype
原型模式的優點及適用場景
使用原型模式創建對象比直接new一個對象在性能上要好的多,因爲Object類的clone方法是一個本地方法,它直接操作內存中的二進制流,特別是複製大對象時,性能的差別非常明顯。
使用原型模式的另一個好處是簡化對象的創建,使得創建對象就像我們在編輯文檔時的複製粘貼一樣簡單。
因爲以上優點,所以在需要重複地創建相似對象時可以考慮使用原型模式。比如需要在一個循環體內創建對象,假如對象創建過程比較複雜或者循環次數很多的話,使用原型模式不但可以簡化創建過程,而且可以使系統的整體性能提高很多。
參考資料: