在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象之外保存這個狀態,這樣以後就可將該對象恢復到原先保存的狀態。
Token
有時候有必要記錄一個對象的內部狀態。為了允許用戶取消不確定的操作或從錯誤中恢復過來,需要實現檢查點和取消機制,而要實現這些機制,你必須事先將狀態信息保存在某處,這樣才能是對象恢復到他們先前的狀態。
以下情況使用Memento模式:
必需保存一個對象在某一時刻的(部分)狀態,這樣以後需要時它能恢復到先前的狀態。 如果一個用接口來讓其它對象直接得到這些狀態,將會暴露對象的實現細節並破壞對象的封裝性。主要目的是保存一個對象的某個狀態,以便在適當的時候恢復對象,個人覺得叫備份模式更形象些,通俗的講下:假設有原始類A,A中有各種屬性,A可以決定需要備份的屬性,備忘錄類B是用來存儲A的一些內部狀態,類C呢,就是一個用來存儲備忘錄的,且只能存儲,不能修改等操作。做個圖來分析一下:
Original類是原始類,裡面有需要保存的屬性value及創建一個備忘錄類,用來保存value值。Memento類是備忘錄類,Storage類是存儲備忘錄的類,持有Memento類的實例,該模式很好理解。直接看源碼:
實現代碼:
數據結構:
public class Original {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Original(String value) {
this.value = value;
}
public Memento createMemento(){
return new Memento(value);
}
public void restoreMemento(Memento memento){
this.value = memento.getValue();
}
}
實現:
public class Memento {
private String value;
public Memento(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
public class Storage {
private Memento memento;
public Storage(Memento memento) {
this.memento = memento;
}
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
測試類:
public class Test {
public static void main(String[] args) {
// 創建原始類
Original origi = new Original(egg);
// 創建備忘錄
Storage storage = new Storage(origi.createMemento());
// 修改原始類的狀態
System.out.println(初始化狀態為: + origi.getValue());
origi.setValue(niu);
System.out.println(修改後的狀態為: + origi.getValue());
// 回復原始類的狀態
origi.restoreMemento(storage.getMemento());
System.out.println(恢復後的狀態為: + origi.getValue());
}
}
“`
輸出:
初始化狀態為:egg
修改後的狀態為:niu
恢復後的狀態為:egg
簡單描述下:新建原始類時,value被初始化為egg,後經過修改,將value的值置為niu,最後倒數第二行進行恢復狀態,結果成功恢復了。其實我覺得這個模式叫“備份-恢復”模式最形象。