基本介紹
備忘錄模式(Memento Pattern):在不破壞封裝性的前提下,捕獲一個物件的內部狀態,並在該物件之外儲存這個狀態。這樣就可以將該物件恢復到原先儲存的狀態
模式結構
Originator(發起者):記錄當前的狀態,負責建立和恢復備忘錄
Memento(備忘錄):負責儲存發起者的狀態,在需要的時候提供發起人需要的狀態
Caretaker(管理者):管理備忘錄
程式碼演示
(這裡我們以單角色、單狀態、單備份來演示,思想是相同的,無非是儲存資料結構上的區別)
備忘錄角色,定義了儲存狀態的變數,可以根據實際需求定義對應的儲存物件
public class Memento {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
發起者角色,儲存狀態,並且可以建立備忘錄和將狀態恢復為備忘錄的值
public class Originator {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Memento createMemento() {
Memento memento = new Memento();
memento.setState(state);
return memento;
}
public void restoreMemento(Memento memento) {
this.state = memento.getState();
}
}
管理者角色,管理了備忘錄
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
測試類
public class Client {
@Test
public void test() {
//設定初始狀態
Originator originator = new Originator();
originator.setState("狀態1");
System.out.println("初始狀態:" + originator.getState());
//建立管理者
Caretaker caretaker = new Caretaker();
caretaker.setMemento(originator.createMemento());
//更新狀態
originator.setState("狀態2");
System.out.println("跟新狀態:" + originator.getState());
//恢復狀態
originator.restoreMemento(caretaker.getMemento());
System.out.println("恢復狀態:" + originator.getState());
}
}
執行結果
初始狀態:狀態1
跟新狀態:狀態2
恢復狀態:狀態1
模式分析
優點:
- 給使用者提供了一種可以恢復狀態的機制,使使用者可以比較方便的回退到某個歷史的狀態
- 實現了資訊的封裝,使使用者不需要關心備忘錄中狀態的儲存細節
缺點:
- 在實際應用中,備忘錄模式都是多狀態和多備份的,發起人角色的狀態需要儲存到備忘錄物件中,對資源的消耗是比較嚴重的,為了節約記憶體,可以配合原型模式使用
應用場景:
- 遊戲的存檔
- CTRL + Z 撤銷
- 瀏覽器的後退
- 資料庫的事務管理
- ... ...