原型模式非常好理解涮母,就是我們從原來(lái)的對(duì)象中復(fù)制出來(lái)一個(gè)一模一樣的對(duì)象,俗稱“克隆”躁愿,多用于創(chuàng)建復(fù)雜或者構(gòu)造耗時(shí)的實(shí)例叛本。
使用場(chǎng)景
1.類初始化需要消化非常多的資源,數(shù)據(jù)攘已、硬件資源等炮赦。
2.通過(guò)new產(chǎn)生一個(gè)對(duì)象需要非常繁瑣的數(shù)據(jù)準(zhǔn)備或訪問(wèn)權(quán)限怜跑。
3.一個(gè)對(duì)象需要提供給其他對(duì)象使用样勃,各個(gè)調(diào)用者可能需要修改其值,但是又要保證其屬性獨(dú)立不相互影響性芬,也就是“保護(hù)性拷貝”峡眶。
比如A有一份文件要給B使用修改,但是A又不希望B更改自己的文件植锉,所以就克隆一份供B使用辫樱。
注意:有時(shí)候通過(guò)實(shí)現(xiàn)Cloneable接口調(diào)用clone方法復(fù)制對(duì)象的時(shí)候并不比new快,所以要考慮創(chuàng)建成本俊庇。
具體實(shí)現(xiàn)
一個(gè)類去實(shí)現(xiàn)Cloneable接口
復(fù)寫clone方法(這是Object類中的方法)
方法中:
XXXDoucument doc = (XXXDoucument)super.clone():
doc.mText = this.mText;
//....各種屬性賦值狮暑。
return doc;
淺拷貝和深拷貝
淺拷貝對(duì)于引用類型只是拷貝了字段引用辉饱。
深拷貝對(duì)于引用型的字段也要使用clone的方式來(lái)拷貝搬男。
Android源碼中的原型模式:
intent類就可以調(diào)用.clone()方法
intent類中的clone方法里面就寫了一句: return new Intent(this);
intent(Intent o)是一個(gè)拷貝構(gòu)造函數(shù),里面有大量諸如this.mAction = o.mAction的句子對(duì)屬性進(jìn)行設(shè)置彭沼。
實(shí)際應(yīng)用:
比如我們有一個(gè)記錄用戶信息的UserSession類缔逛,里面有一個(gè)包級(jí)私有方法setUserInfo(UserInfo info)方法,這個(gè)方法只有在同包級(jí)的登錄網(wǎng)絡(luò)類從網(wǎng)絡(luò)獲得用戶信息了才能調(diào)用姓惑,這個(gè)是沒(méi)問(wèn)題的褐奴。
可是保存用戶信息的UserInfo實(shí)體類中的變量確是public的,會(huì)被人為修改于毙。
為了只在網(wǎng)絡(luò)訪問(wèn)獲取用戶信息后才去修改用戶信息敦冬,避免在其他地方造成變化,我們讓User繼承Cloneable接口唯沮,復(fù)寫clone方法
public User clone(){
? ?User user = null;
? ?try{
? ? ?user = (User)super.clone();
? ?}catch(CloneNotSupportedException e){
? }
? return user;
}
然后再UserSession中g(shù)etLoginedUser里返回克隆類
return userInfo.clone();
這樣在其他地方即使修改了userInfo對(duì)象匪补,也不會(huì)影響從網(wǎng)絡(luò)獲取的最初的userInfo對(duì)象了伞辛。
優(yōu)點(diǎn):是在內(nèi)存中直接進(jìn)行二進(jìn)制流拷貝,例如在一個(gè)循環(huán)體中大量的new對(duì)象時(shí)夯缺,使用clone性能會(huì)好很多蚤氏。
缺點(diǎn):因?yàn)槭侵苯涌寺?duì)象,所以不會(huì)執(zhí)行構(gòu)造函數(shù)踊兜。要注意這一點(diǎn)竿滨。