標(biāo)簽: 設(shè)計(jì)模式初涉
使用場(chǎng)景
簡(jiǎn)單點(diǎn)說(shuō)就是克隆對(duì)象邀窃!適用場(chǎng)景如下:
- 1.當(dāng)初始化類對(duì)象需要消耗非常多資源家坎,或者說(shuō)要進(jìn)行繁瑣
的數(shù)據(jù)準(zhǔn)備或者權(quán)限牍陌,如果想簡(jiǎn)化創(chuàng)建疮茄,可以使用原型模式埂陆。 - 2.一個(gè)對(duì)象提供給其他對(duì)象訪問(wèn),而各個(gè)調(diào)用者可能都需要
修改對(duì)象的值娃豹,可以考慮使用原型模式克隆多個(gè)對(duì)象供調(diào)用者
使用(保護(hù)性拷貝)
組成部分(三個(gè)角色):
-
Prototype —— 聲明一個(gè)克隆自身的接口焚虱,用于約束想要
克隆自己的類,要求實(shí)現(xiàn)定義的克隆方法懂版。 -
ConcretePrototype —— 實(shí)現(xiàn)Prototype接口的類鹃栽,這些類
真正實(shí)現(xiàn)克隆自身的相關(guān)代碼。 - Client —— 客戶端用戶躯畴,調(diào)用類
UML類圖如下:
Java中的 == 與 equals 的區(qū)別
==民鼓,如果是對(duì)比的基本數(shù)據(jù)類型(int,long等),比較存儲(chǔ)的值是否相等蓬抄,
如果對(duì)比的是引用型的變量丰嘉,比較的是所指向的對(duì)象地址是否相等equals,不能用于比較基本數(shù)據(jù)類型嚷缭,如果沒(méi)對(duì)equals()方法進(jìn)行
重寫(xiě)饮亏,比較的是指向的對(duì)象地址,如果想要比較對(duì)象內(nèi)容阅爽,需要自行重寫(xiě)
方法路幸,做相應(yīng)的判斷!8段獭<螂取!String調(diào)equals是可以判斷內(nèi)容是否一樣百侧,是
因?yàn)閷?duì)equals()方法進(jìn)行了重寫(xiě)砰识,具體自己參見(jiàn)源碼!
克隆必須滿足的條件(三個(gè))
- 1.對(duì)任何的對(duì)象x佣渴,都有:x.clone()!=x 辫狼,即不是同一對(duì)象、
- 2.對(duì)任何的對(duì)象x观话,都有:x.clone().getClass==x.getClass()予借,即對(duì)象類型一致
- 3.如果對(duì)象obj的equals()方法定義恰當(dāng)?shù)脑捲狡剑敲?strong>obj.clone().equals(obj)
應(yīng)當(dāng)是成立的频蛔。(推薦灵迫,不強(qiáng)制)
Java中如何使用:
Prototype原型類(想被克隆的類)實(shí)現(xiàn)Cloneable接口,重寫(xiě)clone()方法晦溪。
調(diào)用:
ConcretePrototype cp1 = new ConcretePrototype();
ConcretePrototype cp2 = (ConcretePrototype)cp1.clone();
示例代碼
通過(guò)一個(gè)示例代碼來(lái)學(xué)習(xí)用法瀑粥,以及驗(yàn)證一些疑問(wèn)
1.供引用的類:Money.java
2.實(shí)現(xiàn)Cloneable接口的類:Assets.java,核心就是重寫(xiě)clone方法而已
3.調(diào)用類:Wealth.java
運(yùn)行結(jié)果:
結(jié)果分析得出結(jié)論:
- 1.執(zhí)行克隆方法三圆,不會(huì)調(diào)用構(gòu)造方法
- 2.克隆會(huì)生成的新的對(duì)象變量狞换,指向的卻是同一個(gè)內(nèi)存地址!
- 3.克隆前后數(shù)據(jù)類型一致舟肉!
- 4.克隆的時(shí)候修噪,類中基本數(shù)據(jù)類型的屬性會(huì)新建,但是引用類型的
只會(huì)生成個(gè)新的引用變量路媚,引用變量的地址依舊指向同一個(gè)內(nèi)存地址黄琼!
深淺拷貝與實(shí)現(xiàn)深拷貝的兩種簡(jiǎn)單套路
上面這種只新建基本類型數(shù)據(jù),不新建引用類型數(shù)據(jù)整慎,稱為淺拷貝脏款,
如果連引用類型數(shù)據(jù)也新建的話,則稱為深拷貝裤园。
深拷貝的其中一種實(shí)現(xiàn)套路是撤师,引用類型也實(shí)現(xiàn)Cloneable接口,然后實(shí)現(xiàn)clone方法
比如讓Money類也實(shí)現(xiàn)Cloneable接口拧揽,重寫(xiě)clone方法:
然后Assets類剃盾,clone方法那里調(diào)這個(gè)方法,為money對(duì)象賦值:
再運(yùn)行一遍淤袜,運(yùn)行結(jié)果:
好的万俗,結(jié)果創(chuàng)建了新的對(duì)象,沒(méi)毛病饮怯,另外這種方法實(shí)現(xiàn)深拷貝
如果屬性的類型也是對(duì)象闰歪,那么需要一直遞歸的克隆下去!蓖墅!
要想深度克隆成功库倘,必須要整個(gè)克隆所涉及的對(duì)象都要正確實(shí)
現(xiàn)克隆方法,如果其中有一個(gè)沒(méi)有正確實(shí)現(xiàn)克隆论矾,那么就會(huì)導(dǎo)致克隆失敗教翩。
這就是深拷貝的其中一種實(shí)現(xiàn)套路,還有另一種套路是 序列化贪壳,
屬性的類型是引用類型的話饱亿,需要實(shí)現(xiàn)Serializable接口,
然后自己寫(xiě)個(gè)方法來(lái)在里面完成對(duì)象轉(zhuǎn)二進(jìn)制流與二進(jìn)制流轉(zhuǎn)
對(duì)象的方法,然后返回克隆后的對(duì)象彪笼!
輸出結(jié)果和上面一致钻注。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
- 1.簡(jiǎn)化對(duì)象創(chuàng)建過(guò)程,當(dāng)對(duì)象創(chuàng)建比較煩瑣時(shí)配猫,可提高創(chuàng)建效率
- 2.深拷貝可保存對(duì)象狀態(tài)幅恋,可將對(duì)象拷貝后保存起來(lái),需要的時(shí)候恢復(fù)
缺點(diǎn):
- 1.深拷貝時(shí)泵肄,屬性存在引用類型多層嵌套的話捆交,為了實(shí)現(xiàn)深克隆,每一層
對(duì)象對(duì)應(yīng)的類都必須支持深克隆腐巢,實(shí)現(xiàn)起來(lái)可能會(huì)比較麻煩
本節(jié)代碼:
https://github.com/coder-pig/DesignPatternsExample/tree/master/3.Prototype%20Pattern