java中的原型模式

原型模式是一種簡單、易使用的創(chuàng)建型設計模式,通過給出一個原型對象來指明所創(chuàng)建的對象的類型,然后用復制這個原型對象的辦法創(chuàng)建出更多同類型的對象臂寝。原型模式要求對象實現(xiàn)一個可以“克隆”自身的接口,這樣就可以通過復制一個實例對象本身來創(chuàng)建一個新的實例摊灭。這樣一來交煞,通過原型實例創(chuàng)建新的對象,就不再需要關心這個實例本身的類型斟或,只要實現(xiàn)了克隆自身的方法素征,就可以通過這個方法來獲取新的對象,而無須再去通過new來創(chuàng)建萝挤。

原型模式的結構圖如下所示:

image

原型模式的參與角色:

(1)客戶角色:客戶類提出創(chuàng)建對象的請求御毅。

(2)抽象原型角色:這是一個抽象角色,通常由一個java接口或抽象類實現(xiàn)怜珍,具體原型都需要實現(xiàn)該接口端蛆。

(3)具體原型角色:客戶端所需要的被復制的對象。

下面還是通過代碼描述該模式的具體使用:

1酥泛、第一個文件:抽象原型文件Prototype.java

public abstract class Prototype implements Cloneable {
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

2今豆、第二個文件:具體原型文件ConcretePrototype1.java

public class ConcretePrototype1 extends Prototype {
    public static int classFlag = 1;

    /**
     * 克隆自身方法
     *
     * @return
     * @throws CloneNotSupportedException
     */
    public Object clone() throws CloneNotSupportedException {
        return (ConcretePrototype1) super.clone();
    }
}

3嫌拣、第三個文件:具體原型文件ConcretePrototype2.java

public class ConcretePrototype2 extends Prototype {
    public static int classFlag = 2;

    /**
     * 克隆自身方法
     *
     * @return
     * @throws CloneNotSupportedException
     */
    public Object clone() throws CloneNotSupportedException {
        return (ConcretePrototype2) super.clone();
    }
}

4、第四個文件:TestMain.java

public class TestMain {
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype prototype1 = new ConcretePrototype1();
        ConcretePrototype1 concretePrototype1 = (ConcretePrototype1) prototype1.clone();
        System.out.println(concretePrototype1.classFlag);
        Prototype prototype2 = new ConcretePrototype2();
        ConcretePrototype2 concretePrototype2 = (ConcretePrototype2) prototype2.clone();
        System.out.println(concretePrototype2.classFlag);
    }
}

看了以上代碼呆躲,大家可能會覺得原型模式其實還是挺簡單的异逐。

我們上面描述的對象創(chuàng)建方法是通過調(diào)用java中的clone方法來復制對象,我看到網(wǎng)上還有另外一種使用new的方式來創(chuàng)建對象插掂,具體原型的寫法如下所示灰瞻。

5、第一個文件:Prototype.java

public interface Prototype {
    public Object clone();
}

6辅甥、第二個文件:ConcretePrototype1.java

public class ConcretePrototype1 implements Prototype {
    @Override
    public Object clone() {
        // 最簡單的克隆酝润,新建一個自身對象,由于沒有屬性就不再復制值了
        Prototype prototype = new ConcretePrototype1();
        return prototype;
    }
}

7璃弄、第三個文件ConcretePrototype2.java

public class ConcretePrototype2 implements Prototype {
    @Override
    public Object clone() {
        //最簡單的克隆要销,新建一個自身對象,由于沒有屬性就不再復制值了
        Prototype prototype = new ConcretePrototype2();
        return prototype;
    }
}

至于以上兩種寫法的區(qū)別就在于一種是直接調(diào)用clone方法實現(xiàn)淺克隆出一個對象夏块,第二種是使用new蕉陋,創(chuàng)建出一個完完全全獨立的新對象,咱就把它稱作是"深克隆"吧拨扶。

至于淺克隆和深克隆的區(qū)別是什么呢,簡單的說:如果一個對象中只有基本類型屬性茁肠,那深克隆和淺克隆效果都是一樣的患民,基本類型數(shù)據(jù)不管是用深克隆還是淺克隆都會被克隆出一份,但如果對象中包含引用對象屬性垦梆,那淺克隆其實這是拷貝了一份引用匹颤,而深克隆確實把整個引用對象都拷貝了一份。

在看了原型模式之后托猩,大家可能會覺得這個跟工廠模式比較的相似印蓖。咱們把工廠模式的結構圖也畫一下,大家對比一下就知道的區(qū)別了京腥。

image

比較明顯原型模式?jīng)]有工廠模式的抽象工廠和具體工廠的實現(xiàn)赦肃,代碼結構要簡單一些,當然你也可以把原型模式的抽象原型理解成一種特殊的工廠公浪。

8他宛、原型模式的優(yōu)點:

(1)根據(jù)客戶端要求實現(xiàn)動態(tài)創(chuàng)建對象,客戶端不需要知道對象的創(chuàng)建細節(jié)欠气,便于代碼的維護和擴展厅各。

(2)使用原型模式創(chuàng)建對象比直接new一個對象在性能上要好的多,因為Object類的clone方法是一個本地方法预柒,它直接操作內(nèi)存中的二進制流队塘,特別是復制大對象時袁梗,性能的差別非常明顯。所以在需要重復地創(chuàng)建相似對象時可以考慮使用原型模式憔古。比如需要在一個循環(huán)體內(nèi)創(chuàng)建對象遮怜,假如對象創(chuàng)建過程比較復雜或者循環(huán)次數(shù)很多的話,使用原型模式不但可以簡化創(chuàng)建過程投放,而且可以使系統(tǒng)的整體性能提高很多奈泪。

(3) 原型模式類似于工廠模式,但它沒有了工廠模式中的抽象工廠和具體工廠的層級關系灸芳,代碼結構更清晰和簡單涝桅。

9、原型模式的注意事項:

(1)使用原型模式復制對象不會調(diào)用類的構造方法烙样。因為對象的復制是通過調(diào)用Object類的clone方法來完成的冯遂,它直接在內(nèi)存中復制數(shù)據(jù),因此不 會調(diào)用到類的構造方法谒获。不但構造方法中的代碼不會執(zhí)行蛤肌,甚至連訪問權限都對原型模式無效。還記得單例模式嗎批狱?單例模式中裸准,只要將構造方法的訪問權限設置為 private型,就可以實現(xiàn)單例赔硫。但是clone方法直接無視構造方法的權限炒俱,所以,單例模式與原型模式是沖突的爪膊。

(2)在使用時要注意深拷貝與淺拷貝的問題权悟。clone方法只會拷貝對象中的基本的數(shù)據(jù)類型,對于數(shù)組推盛、容器對象峦阁、引用對象等都不會拷貝,這就是淺拷貝耘成。如果要實現(xiàn)深拷貝榔昔,必須將原型模式中的數(shù)組、容器對象瘪菌、引用對象等另行拷貝件豌。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市控嗜,隨后出現(xiàn)的幾起案子茧彤,更是在濱河造成了極大的恐慌,老刑警劉巖疆栏,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件曾掂,死亡現(xiàn)場離奇詭異惫谤,居然都是意外死亡,警方通過查閱死者的電腦和手機珠洗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門溜歪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人许蓖,你說我怎么就攤上這事蝴猪。” “怎么了膊爪?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵自阱,是天一觀的道長。 經(jīng)常有香客問我米酬,道長沛豌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任赃额,我火速辦了婚禮加派,結果婚禮上,老公的妹妹穿的比我還像新娘跳芳。我一直安慰自己芍锦,他們只是感情好,可當我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布飞盆。 她就那樣靜靜地躺著娄琉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪桨啃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天檬输,我揣著相機與錄音照瘾,去河邊找鬼。 笑死丧慈,一個胖子當著我的面吹牛析命,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逃默,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼鹃愤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了完域?” 一聲冷哼從身側響起软吐,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吟税,沒想到半個月后凹耙,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姿现,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年肖抱,在試婚紗的時候發(fā)現(xiàn)自己被綠了备典。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡意述,死狀恐怖提佣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情荤崇,我是刑警寧澤拌屏,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布选调,位于F島的核電站酝惧,受9級特大地震影響瑰抵,放射性物質(zhì)發(fā)生泄漏署惯。R本人自食惡果不足惜责嚷,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一箕慧、第九天 我趴在偏房一處隱蔽的房頂上張望亦渗。 院中可真熱鬧又兵,春花似錦带兜、人聲如沸枫笛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽刑巧。三九已至,卻和暖如春无畔,著一層夾襖步出監(jiān)牢的瞬間啊楚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工浑彰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留恭理,地道東北人。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓郭变,卻偏偏與公主長得像颜价,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子诉濒,可洞房花燭夜當晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容