???名稱:Prototype(原型模式)
?
?? 意圖:用原型實(shí)例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。
?
?? 適用環(huán)境:當(dāng)一個(gè)系統(tǒng)應(yīng)該獨(dú)立于它的產(chǎn)品創(chuàng)建、構(gòu)成和表示時(shí),要使用Prototype模式;以及要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí),例如,通過動(dòng)態(tài)裝載;或者為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠類層次時(shí);或者 當(dāng)一個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)。建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便一些。
????結(jié)構(gòu)圖:如下
?
java中提供了clone()來實(shí)現(xiàn)對象克隆。所以prototype模式變得了很簡單。
只要實(shí)現(xiàn)接口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;
????????}
????????
????}
}
深拷貝:上面簡單的調(diào)用了Object的clone()方法,此時(shí)只是進(jìn)行了淺拷貝,若Monkey里含有對象成員staff,則用上述方法克隆出的對象與原對象指向同一個(gè)對象staff,顯然有時(shí)候這并不滿足要求。
深拷貝是指:被復(fù)制的對象的所有變量都含有與原來對象相同的值,除去那些引用其它變量的對象。
在Java中可以利用串行化(Serivalized)來實(shí)現(xiàn)深拷貝,先使一個(gè)對象實(shí)現(xiàn)Serializable接口,然后把對象(對象的一個(gè)拷貝)寫入一個(gè)流中,后再從流里讀出來,這樣便可重復(fù)創(chuàng)建對象。
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必須實(shí)現(xiàn)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(); //從流中讀出
????}
????}
使用原型模式,有以下結(jié)論:
?????????1.在運(yùn)行時(shí),可以根據(jù)需要,以復(fù)制的方式增加和刪除類。(登記型原形模式)
???????? 2.可以基于程序條件,在運(yùn)行時(shí)修改一個(gè)類的內(nèi)部數(shù)據(jù)表示。
???????? 3.還可以在運(yùn)行時(shí)指定新的對象,而無需創(chuàng)建一系列類和繼承結(jié)構(gòu)。
參考資料:《Java與模式》
????????????????????《Java設(shè)計(jì)模式》
?????????????????? ? http://www.lvjiyong.com/books/DesignPatterns/16.html
?
?? 意圖:用原型實(shí)例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。
?
?? 適用環(huán)境:當(dāng)一個(gè)系統(tǒng)應(yīng)該獨(dú)立于它的產(chǎn)品創(chuàng)建、構(gòu)成和表示時(shí),要使用Prototype模式;以及要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí),例如,通過動(dòng)態(tài)裝載;或者為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠類層次時(shí);或者 當(dāng)一個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)。建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便一些。
????結(jié)構(gòu)圖:如下
?

java中提供了clone()來實(shí)現(xiàn)對象克隆。所以prototype模式變得了很簡單。
只要實(shí)現(xiàn)接口Cloneable就可以了

















?

??????? ??public?Object?clone()

















深拷貝:上面簡單的調(diào)用了Object的clone()方法,此時(shí)只是進(jìn)行了淺拷貝,若Monkey里含有對象成員staff,則用上述方法克隆出的對象與原對象指向同一個(gè)對象staff,顯然有時(shí)候這并不滿足要求。
深拷貝是指:被復(fù)制的對象的所有變量都含有與原來對象相同的值,除去那些引用其它變量的對象。
在Java中可以利用串行化(Serivalized)來實(shí)現(xiàn)深拷貝,先使一個(gè)對象實(shí)現(xiàn)Serializable接口,然后把對象(對象的一個(gè)拷貝)寫入一個(gè)流中,后再從流里讀出來,這樣便可重復(fù)創(chuàng)建對象。





























使用原型模式,有以下結(jié)論:
?????????1.在運(yùn)行時(shí),可以根據(jù)需要,以復(fù)制的方式增加和刪除類。(登記型原形模式)
???????? 2.可以基于程序條件,在運(yùn)行時(shí)修改一個(gè)類的內(nèi)部數(shù)據(jù)表示。
???????? 3.還可以在運(yùn)行時(shí)指定新的對象,而無需創(chuàng)建一系列類和繼承結(jié)構(gòu)。
參考資料:《Java與模式》
????????????????????《Java設(shè)計(jì)模式》
?????????????????? ? http://www.lvjiyong.com/books/DesignPatterns/16.html