備忘錄( Memento)模式: 在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態。這樣以后就可將該對象恢復到原先保存的狀態。

適用性:

  • 必須保存一個對象在某一個時刻的(部分)狀態, 這樣以后需要時它才能恢復到先前的狀態。
  • 如果一個用接口來讓其它對象直接得到這些狀態,將會暴露對象的實現細節并破壞對象的封裝性。


memento.bmp

所涉及的角色:

備忘錄角色:將發起人 (Originator) 的對象內部狀態存儲起來,備忘錄可以根據發起人對象的的判斷來決定存儲多少發起人( Originator )對象的內部狀態。奮忘錄同時可以保護其內容不被發起人 (Originator) 對象之外的任何對象所索。

?

發起人 (Originator) 角色:創建一個含有當前的內部狀態的的備忘錄對象 , 使用備忘錄對象存儲內部狀態。

?

負責人( Caretaker )角色:負責保存備忘錄對象,不檢查備忘錄對象的內容。


一個簡單的例子:
備忘錄角色

package ?Memento;

public ? class ?Memento {
????
private ?String?state;
????
// 構造方法
???? public ?Memento(String?state) {
????????
this .state = state;
????}

????
// 狀態的賦值方法
???? public ? void ?setState(String?state) {
????????
this .state = state;
????}

????
// 狀態的取值方法
???? public ?String?getState() {
????????
return ? this .state;
????}

}
發起人 (Originator) 角色:
package?Memento;

public?class?Originator{
????
private?String?state;
????
//工廠方法,返回一個新的備忘錄對象
????public?Memento?createMemento(){
????????
return?new?Memento(state);
????}

????
//將發起人的狀態恢復到備忘錄對象所保存的狀態
????public?void?restoreMemento(Memento?memento){
????????
this.state=memento.getState();
????}

????
//狀態的賦值方法
????public?void?setState(String?state){
????????
this.state=state;
????????System.out.println(
"Current?State:"+state);
????}

????
//狀態取值方法
????public??String?getState(){
????????
return?this.state;
????}

}
負責人( Caretaker )角色:
package?Memento;

public?class?Caretaker{
????
private?Memento?memento;
????
//備忘錄的取值方法
????public?Memento?retriveMemento(){
????????
return?this.memento;
????}

????
//備忘錄的賦值方法
????public?void?saveMemento(Memento?memento){
????????
this.memento=memento;
????}


}

客戶端:
package?Memento;

public?class?Client{
????
private?static?Originator?o=new?Originator();
????
private?static?Caretaker?c=new?Caretaker();
????
public?static?void?main(String[]?args){
????????
//改變發起人對象的狀態
????????o.setState("ON");
????????
//創建備忘錄對象?并將發起人對象狀態保存起來
????????c.saveMemento(o.createMemento());
????????
//修改發起人的對象狀態
????????o.setState("OFF");
????????
//恢復發起人對象的狀態
????????o.restoreMemento(c.retriveMemento());
????????
//輸出當前發起人對象的狀態
????????System.out.println(o.getState());
????????
????}

}


參考資料:《java與模式》
《設計模式速查找手冊》