使用場(chǎng)景
如果 對(duì)象的創(chuàng)建成本比較大,而 同一個(gè)類的不同對(duì)象之間差別不大(大部分字段都相同),在這種情況下,我們可以利用對(duì)已有對(duì)象(原型)進(jìn)行復(fù)制(或者叫拷貝)的方式來創(chuàng)建新對(duì)象,以達(dá)到節(jié)省創(chuàng)建時(shí)間的目的。
何為“對(duì)象的創(chuàng)建成本比較大”?
如果對(duì)象中的數(shù)據(jù)需要經(jīng)過復(fù)雜的計(jì)算才能得到(比如排序、計(jì)算哈希值),或者需要從 RPC、網(wǎng)絡(luò)、數(shù)據(jù)庫(kù)、文件系統(tǒng)等非常慢速的 IO 中讀取,這種情況下,我們就可以利用原型模式,從其他已有對(duì)象中直接拷貝得到,而不用每次在創(chuàng)建新對(duì)象的時(shí)候,都重復(fù)執(zhí)行這些耗時(shí)的操作。
原型模式的實(shí)現(xiàn)方式:深拷貝和淺拷貝
要使用原型模式,我們就需要對(duì)對(duì)象進(jìn)行拷貝,這里我們要先了解下深拷貝和淺拷貝。
淺拷貝和深拷貝的區(qū)別在于,淺拷貝只會(huì)復(fù)制數(shù)據(jù)的內(nèi)存地址,而深拷貝會(huì)復(fù)制數(shù)據(jù)本身。因此,淺拷貝與原始對(duì)象共享數(shù)據(jù)對(duì)象,原始對(duì)象如果修改了數(shù)據(jù)值,拷貝的對(duì)象也會(huì)變?yōu)樾碌闹?;而深拷貝得到的是一份完完全全?dú)立的對(duì)象,不會(huì)受原對(duì)象影響。
在 Java 語言中,Object 類的 clone() 方法執(zhí)行的就是我們剛剛說的淺拷貝。它只會(huì)拷貝對(duì)象中的基本數(shù)據(jù)類型的數(shù)據(jù)(比如,int、long),以及引用對(duì)象的內(nèi)存地址,不會(huì)遞歸地拷貝引用對(duì)象本身。
那如何實(shí)現(xiàn)深拷貝呢?
- 遞歸拷貝對(duì)象、對(duì)象的引用對(duì)象以及引用對(duì)象的引用對(duì)象……直到要拷貝的對(duì)象只包含基本數(shù)據(jù)類型數(shù)據(jù),沒有引用對(duì)象為止。
- 先將對(duì)象序列化,然后再反序列化成新的對(duì)象。