???名稱:Prototype(原型模式)
?
?? 意圖:用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。
?
?? 適用環境:當一個系統應該獨立于它的產品創建、構成和表示時,要使用Prototype模式;以及要實例化的類是在運行時刻指定時,例如,通過動態裝載;或者為了避免創建一個與產品類層次平行的工廠類層次時;或者 當一個類的實例只能有幾個不同狀態組合中的一種時。建立相應數目的原型并克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。

????結構圖:如下

?Prototype.gif

java中提供了clone()來實現對象克隆。所以prototype模式變得了很簡單。

只要實現接口Cloneable就可以了

package?prototype;
import?java.util.Date;
import?java.io.*;
public?class?Monkey?implements?Cloneable{
????
private?int?height;
????
private?int?weight;
????
private?GoldRingedStaff?staff;
????
private?Date?birthDate;
????
????
public?Monkey(){
????????birthDate
=new?Date();
????????staff
=new?GoldRingedStaff();
????}
?
???? ????
//淺拷貝
???????
??public?Object?clone(){
????????Monkey?temp
=null;
????????
try{
????????????temp
=(Monkey)super.clone();
????????}
catch(CloneNotSupportedException?e){
????????}
finally{
????????????
return?temp;
????????}

????????
????}

}

深拷貝:上面簡單的調用了Object的clone()方法,此時只是進行了淺拷貝,若Monkey里含有對象成員staff,則用上述方法克隆出的對象與原對象指向同一個對象staff,顯然有時候這并不滿足要求。
深拷貝是指:被復制的對象的所有變量都含有與原來對象相同的值,除去那些引用其它變量的對象。
在Java中可以利用串行化(Serivalized)來實現深拷貝,先使一個對象實現Serializable接口,然后把對象(對象的一個拷貝)寫入一個流中,后再從流里讀出來,這樣便可重復創建對象。
package?prototype;
import?java.util.Date;
import?java.io.*;
public?class?Monkey?implements?Cloneable,Serializable{
????
private?int?height;
????
private?int?weight;
????
private?GoldRingedStaff?staff;?? //GoldRingedStaff必須實現Serializable接口
????
private?Date?birthDate;
????
????
public?Monkey(){
????????birthDate
=new?Date();
????????staff
=new?GoldRingedStaff();
????}

????????
//深拷貝
????public?Object?deepClone()throws?IOException,ClassNotFoundException{
????????ByteArrayOutputStream?bo
=new?ByteArrayOutputStream();
????????ObjectOutputStream?oo
=new?ObjectOutputStream(bo);
????????oo.writeObject(
this); //寫入流中
????????ByteArrayInputStream?bi
=new?ByteArrayInputStream(bo.toByteArray());
????????ObjectInputStream?oi
=new?ObjectInputStream(bi);
????????
return?oi.readObject(); //從流中讀出
????}

????}

使用原型模式,有以下結論:
?????????1.在運行時,可以根據需要,以復制的方式增加和刪除類。(登記型原形模式)
???????? 2.可以基于程序條件,在運行時修改一個類的內部數據表示。
???????? 3.還可以在運行時指定新的對象,而無需創建一系列類和繼承結構。


參考資料:《Java與模式》
????????????????????《Java設計模式》
?????????????????? ? http://www.lvjiyong.com/books/DesignPatterns/16.html