GOF設(shè)計(jì)模式學(xué)習(xí)筆記(二)---Prototype模式
Posted on 2007-05-14 11:17 久城 閱讀(2533) 評(píng)論(5) 編輯 收藏 所屬分類: GOF設(shè)計(jì)模式老板說:“給我蓋一座大樓。”
工程師說:“蓋什么樣的大樓呢?”
老板指著身后的一座樓說:“和那個(gè)一模一樣的。”
從老板的角度來講,他采用的就是,Prototype模式,即原型模式。否則,他需要再花費(fèi)一些時(shí)間和工程師一點(diǎn)一點(diǎn)的探討關(guān)于大樓的一些設(shè)計(jì)問題。
所謂的原型模式,就是用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。
JAVA的Object.clone()的存在,使得這個(gè)模型的學(xué)習(xí)變得簡單了許多。
一.搭橋過河
過河是一門大學(xué)問
首先研究一下JAVA的clone技術(shù)。
我理解的很簡單,無非是把一個(gè)對(duì)象進(jìn)行復(fù)制粘貼。那么,來看一下JAVA語言中是如何來實(shí)現(xiàn)的這個(gè)步驟的。我們依次需要知道以下這些事。
1.Object對(duì)象中有一個(gè)clone()方法。而且是protected。
2.繼承于Object的類一般都可以實(shí)現(xiàn)這個(gè)方法(有特殊的,比如StringBuffer等,官方定的,不去研究它)。
3.想被clone的對(duì)象需要實(shí)現(xiàn)接口Cloneable。如果此對(duì)象的類不能實(shí)現(xiàn)接口Cloneable,則會(huì)拋出CloneNotSupportedExcetion。
4.所有的數(shù)組都被視為實(shí)現(xiàn)接口Cloneable。
5.clone分為淺clone(又稱影子clone)和深clone。
6.Object類本身不實(shí)現(xiàn)接口Cloneable,所以在類為Object的對(duì)象上調(diào)用clone方法,將會(huì)導(dǎo)致在運(yùn)行時(shí)拋出異常。
首先來看一個(gè)能夠?qū)崿F(xiàn)clone類的小例子。
//本文代碼參考于http://blog.csdn.net/tiewen/archive/2005/08/05/446301.aspx

class CloneClass implements Cloneable
{
public int aInt;


public Object clone()
{
CloneClass o = null;

try
{
o = (CloneClass) super.clone();

} catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return o;
}
}
至于淺clone和深clone,無非就是一個(gè)程度問題。再來看一個(gè)例子。

class UnCloneA
{
private int i;


public UnCloneA(int ii)
{
i = ii;
}


public void doublevalue()
{
i *= 2;
}


public String toString()
{
return Integer.toString(i);
}
}


class CloneB implements Cloneable
{
public int aInt;

public UnCloneA unCA = new UnCloneA(111);


public Object clone()
{
CloneB o = null;

try
{
o = (CloneB) super.clone();

} catch (CloneNotSupportedException e)
{
e.printStackTrace();
}
return o;
}
}


class CloneMain
{

public static void main(String[] a)
{
CloneB b1 = new CloneB();
b1.aInt = 11;
System.out.println("before clone,b1.aInt = " + b1.aInt);
System.out.println("before clone,b1.unCA = " + b1.unCA);
CloneB b2 = (CloneB) b1.clone();
b2.aInt = 22;
b2.unCA.doublevalue();
System.out.println("=================================");
System.out.println("after clone,b1.aInt = " + b1.aInt);
System.out.println("after clone,b1.unCA = " + b1.unCA);
System.out.println("=================================");
System.out.println("after clone,b2.aInt = " + b2.aInt);
System.out.println("after clone,b2.unCA = " + b2.unCA);
}
}
輸出結(jié)果為:
/** RUN RESULT:
before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 222
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222
*/
可見,當(dāng)執(zhí)行clone這個(gè)動(dòng)作的時(shí)候,系統(tǒng)首先開辟一個(gè)和它一樣的空間。然后分別對(duì)其內(nèi)容進(jìn)行復(fù)制。復(fù)制過程中,如果是基本類型,沒什么說的,直接把值復(fù)制過來。如果不是基本類型,復(fù)制的則是該類型對(duì)象的引用。
這樣的clone就是所謂的淺clone。那很顯然,如果上面復(fù)制的過程中,對(duì)于非基本類型實(shí)現(xiàn)的不是一個(gè)引用復(fù)制,而是創(chuàng)建一個(gè)新的一樣的對(duì)象(其實(shí)也是一個(gè)clone步驟),那么就是所謂的深clone。對(duì)于深度克隆只不過是clone的一種擴(kuò)展,還有N深clone等等。對(duì)于這些,和我們要研究的原型模式?jīng)]有多少關(guān)系。不想去研究。
要用它,就要知道它的優(yōu)點(diǎn)。合理的利用它的優(yōu)點(diǎn)來為我們服務(wù)。做人也一樣,不要總拿自己的短處去比別人的長處。要知道,每個(gè)人都是不一樣的,每個(gè)人都有自己的長處和短處。這就是以長克短。
JAVA中的clone方法,其實(shí)現(xiàn)是native的。這也就意味著它的執(zhí)行效率是遠(yuǎn)高于new一個(gè)新對(duì)象的。所以,當(dāng)需要生成大量相似對(duì)象的時(shí)候,可以考慮下應(yīng)用clone,也就是原形模式。
我的項(xiàng)目經(jīng)驗(yàn)幾乎為0,單純從理解的角度去想的。
至于其它的應(yīng)用,還有待前輩們指點(diǎn)。我再不斷補(bǔ)充。
工程師說:“蓋什么樣的大樓呢?”
老板指著身后的一座樓說:“和那個(gè)一模一樣的。”
從老板的角度來講,他采用的就是,Prototype模式,即原型模式。否則,他需要再花費(fèi)一些時(shí)間和工程師一點(diǎn)一點(diǎn)的探討關(guān)于大樓的一些設(shè)計(jì)問題。
所謂的原型模式,就是用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。
JAVA的Object.clone()的存在,使得這個(gè)模型的學(xué)習(xí)變得簡單了許多。
一.搭橋過河
過河是一門大學(xué)問
首先研究一下JAVA的clone技術(shù)。
我理解的很簡單,無非是把一個(gè)對(duì)象進(jìn)行復(fù)制粘貼。那么,來看一下JAVA語言中是如何來實(shí)現(xiàn)的這個(gè)步驟的。我們依次需要知道以下這些事。
1.Object對(duì)象中有一個(gè)clone()方法。而且是protected。
2.繼承于Object的類一般都可以實(shí)現(xiàn)這個(gè)方法(有特殊的,比如StringBuffer等,官方定的,不去研究它)。
3.想被clone的對(duì)象需要實(shí)現(xiàn)接口Cloneable。如果此對(duì)象的類不能實(shí)現(xiàn)接口Cloneable,則會(huì)拋出CloneNotSupportedExcetion。
4.所有的數(shù)組都被視為實(shí)現(xiàn)接口Cloneable。
5.clone分為淺clone(又稱影子clone)和深clone。
6.Object類本身不實(shí)現(xiàn)接口Cloneable,所以在類為Object的對(duì)象上調(diào)用clone方法,將會(huì)導(dǎo)致在運(yùn)行時(shí)拋出異常。
首先來看一個(gè)能夠?qū)崿F(xiàn)clone類的小例子。






















至于淺clone和深clone,無非就是一個(gè)程度問題。再來看一個(gè)例子。






































































輸出結(jié)果為:
/** RUN RESULT:
before clone,b1.aInt = 11
before clone,b1.unCA = 111
=================================
after clone,b1.aInt = 11
after clone,b1.unCA = 222
=================================
after clone,b2.aInt = 22
after clone,b2.unCA = 222
*/
可見,當(dāng)執(zhí)行clone這個(gè)動(dòng)作的時(shí)候,系統(tǒng)首先開辟一個(gè)和它一樣的空間。然后分別對(duì)其內(nèi)容進(jìn)行復(fù)制。復(fù)制過程中,如果是基本類型,沒什么說的,直接把值復(fù)制過來。如果不是基本類型,復(fù)制的則是該類型對(duì)象的引用。
這樣的clone就是所謂的淺clone。那很顯然,如果上面復(fù)制的過程中,對(duì)于非基本類型實(shí)現(xiàn)的不是一個(gè)引用復(fù)制,而是創(chuàng)建一個(gè)新的一樣的對(duì)象(其實(shí)也是一個(gè)clone步驟),那么就是所謂的深clone。對(duì)于深度克隆只不過是clone的一種擴(kuò)展,還有N深clone等等。對(duì)于這些,和我們要研究的原型模式?jīng)]有多少關(guān)系。不想去研究。
關(guān)于JAVA的clone技術(shù),對(duì)我來說,理解這些就夠了。其它的,就是進(jìn)一步的擴(kuò)展及應(yīng)用。
二.以長克短
什么時(shí)候會(huì)想到用原型模式呢
這個(gè)我們學(xué)習(xí)任何一項(xiàng)技術(shù)都要問自己的問題。
要用它,就要知道它的優(yōu)點(diǎn)。合理的利用它的優(yōu)點(diǎn)來為我們服務(wù)。做人也一樣,不要總拿自己的短處去比別人的長處。要知道,每個(gè)人都是不一樣的,每個(gè)人都有自己的長處和短處。這就是以長克短。
JAVA中的clone方法,其實(shí)現(xiàn)是native的。這也就意味著它的執(zhí)行效率是遠(yuǎn)高于new一個(gè)新對(duì)象的。所以,當(dāng)需要生成大量相似對(duì)象的時(shí)候,可以考慮下應(yīng)用clone,也就是原形模式。
我的項(xiàng)目經(jīng)驗(yàn)幾乎為0,單純從理解的角度去想的。
至于其它的應(yīng)用,還有待前輩們指點(diǎn)。我再不斷補(bǔ)充。
歡迎來訪!^.^!
本BLOG僅用于個(gè)人學(xué)習(xí)交流!
目的在于記錄個(gè)人成長.
所有文字均屬于個(gè)人理解.
如有錯(cuò)誤,望多多指教!不勝感激!