? ?“臥槽!”,小A一聲極其粗魯?shù)呐R瞬間打破了公司午后的寧?kù)o。
? ? “你這是怎么了?”,號(hào)稱公司“八卦第一人”的小B瞬間到達(dá)了戰(zhàn)場(chǎng)。
? ? “這兩天我不是一直在找x項(xiàng)目中的bug嗎,就在剛才,還沒(méi)來(lái)得及體會(huì)找到bug的喜悅,電腦死機(jī)了!”小A憤憤的說(shuō)到。
? ? “ 那你再重新找一下不就行了?!?,小C一臉輕松地走過(guò)來(lái)。
? ? “可是我的數(shù)據(jù)都還沒(méi)有備份,原本想等到找到之后再備份,結(jié)果電腦死機(jī)了!”小A有氣無(wú)力的應(yīng)著。
? ? “現(xiàn)在說(shuō)什么都沒(méi)用了,就當(dāng)吃一塹長(zhǎng)一智了,還是盡快再做一遍吧,老大不就給了你三天時(shí)間嗎?”,小D拍了拍小A的肩膀慢慢走遠(yuǎn)了。
? ? “唉!”,小A邊嘆氣邊打開(kāi)了電腦.......
? ? ? ? 相信上邊的場(chǎng)景大家都不陌生吧,僅僅因?yàn)橥藗渫?,不僅使我們的成功后的喜悅瞬間煙消云散,還使得我們不得不重新再做一遍,心情瞬間就不美了。那么如何有效的避免上述場(chǎng)景的出現(xiàn)呢?對(duì),就是將數(shù)據(jù)備份。那么接下來(lái)我們就來(lái)談?wù)勗贘ava程序設(shè)計(jì)中的備份,也就是我們常說(shuō)的二十三種設(shè)計(jì)模式中的備忘錄模式。
? ? ? 備忘錄(Memento)模式又稱標(biāo)記(Token)模式。GOF給備忘錄模式的定義為:在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。
? ? ?備忘錄模式結(jié)構(gòu)圖

其實(shí)從上圖我們便可以看出來(lái)備忘錄模式可以說(shuō)是有三個(gè)部分組成:
1. ? ? ?發(fā)起者角色(Originator):負(fù)責(zé)創(chuàng)建一個(gè)備忘錄用以記錄當(dāng)前時(shí)刻它的內(nèi)部狀態(tài),并可以使用備忘錄恢復(fù)內(nèi)部狀態(tài)。
2. ? ? ? 備忘錄角色(Memento):負(fù)責(zé)存儲(chǔ)Originator對(duì)象的內(nèi)部狀態(tài),并可以防止Originator以外的其他對(duì)象訪問(wèn)備忘錄。
3. ? ? ? ?管理者角色(Manager):負(fù)責(zé)保存好備忘錄。
? 讀到這里相信大家對(duì)備忘錄已經(jīng)有一定的理解了,再來(lái)看一段代碼:
代碼示例?:
Originator(發(fā)起人類(lèi))
public class Originator{
? ? ? ? privateString state;//需要保存的屬性
????// 創(chuàng)建備忘錄,將需要保存的信息導(dǎo)入并實(shí)例化出Memento對(duì)象
public Memento create Memento(){
return new Memento(state);
}
//恢復(fù)備忘錄,將memento導(dǎo)入并恢復(fù)相關(guān)數(shù)據(jù)
?public void setMemento(Memento memento){
?state = memento.getState();
?}
// 顯示數(shù)據(jù)
public void show(){
System.out.println("state="+state);
}
}
Menmento(備忘錄):
public class Memento{
private String state;
public Memento(String state){
this.state = state;
}
}
Manager(管理者):
public class Manager{
private Memento memento;
}
客戶端
public class Memo{
public static void main(String[] args){
//初始狀態(tài)為on
Originator o = new Originator();
o.setState("on");
o.show();
//保存狀態(tài),隱藏了Originator的實(shí)現(xiàn)細(xì)節(jié)
Manager?c = new Manager();
c.setMemento(o.createMemento());
o.setState("off");
o.show();
//恢復(fù)狀態(tài)
o.setMemento(c.getMemento());
o.show();
}
}
看完有沒(méi)有發(fā)現(xiàn)這種模式的優(yōu)點(diǎn):當(dāng)發(fā)起人角色中的狀態(tài)改變時(shí),有可能這是個(gè)錯(cuò)誤的改變,我們使用備忘錄模式就可以把這個(gè)錯(cuò)誤的改變還原。
備份的狀態(tài)是保存在發(fā)起人角色之外的,這樣,發(fā)起人角色就不需要對(duì)各個(gè)備份的狀態(tài)進(jìn)行管理。
不過(guò)萬(wàn)事萬(wàn)物皆有兩面性,細(xì)心的讀者肯定也發(fā)現(xiàn)了它的不足,在實(shí)際應(yīng)用中,備忘錄模式都是多狀態(tài)和多備份的,發(fā)起人角色的狀態(tài)需要存儲(chǔ)到備忘錄對(duì)象中,對(duì)資源的消耗是比較嚴(yán)重的。
如果有需要提供回滾操作的需求,使用備忘錄模式非常適合,比如jdbc的事務(wù)操作,文本編輯器的Ctrl+Z恢復(fù)等。
? 以上便是本人對(duì)備忘錄設(shè)計(jì)模式的理解了,希望對(duì)大家有所幫助,如果有什么不足之處還希望大家多多指點(diǎn),感激不盡!
版權(quán)聲明:本文為博主原創(chuàng)文章,未經(jīng)博主允許不得轉(zhuǎn)載。http://www.itdecent.cn/writer#/notebooks/28204711/notes/32165896