【デザインパターン】【GoF】【Java】Mementoパターン

使いどころ

 * Undo機能
  => 一度変化してしまったインスタンスを、
  「少し前の状態に戻したい」「ある時点の状態に戻したい」などの時に使用する

 ※ ただし、完全に複製するのではなく、必要な情報のみを保持しておき、
     必要なデータのみを復元する

サンプル

Memento.java

* 「Originator」の内部情報(フィールド値)を保持するクラス
// 「Originator」の内部情報(フィールド値)を保持するクラス
public class Memento {
   int param1;
   String param2;
   Memento(int param1, String param2) {
      this.param1 = param1;
      this.param2 = param2;
   }
   public int getParam1() {
      return this.param1;
   }
   public String getParam2() {
      return this.param2;
   }
}

Originator.java

* 自身の状態を「Memento」として保持し、与えられた「Memento」から自身の状態を復元するクラス
// 自身の状態を「Memento」として保持する
// 与えられた「Memento」から自身の状態を復元するクラス
public class Originator {
   private int param1;
   private String param2;
   public Originator() {
      this.param1 = 0;
      this.param2 = "";
   }
   public void countParam1(int param1) {
      this.param1 = this.param1 + param1;
   }
   public void appendParam2(String param2) {
      this.param2 = this.param2 + param2;
   }
   public int getParam1() {
      return this.param1;
   }
   public String getParam2() {
      return this.param2;
   }
   /// 自分の状態を保存した「Memento」を作成するメソッド
   public Memento createMemento() {
      return new Memento(this.param1, this.param2);
   }
   // 要求された「Memento」に状態を戻すメソッド
   public void restoreMemento(Memento memento) {
      this.param1 = memento.param1;
      this.param2 = memento.param2;
   }
}

Caretaker.java

* 「Originator」の状態を保存したい場合、「Memento」を保持する
* 「Originator」の状態を元に戻したい場合、「Memento」を受け渡す
public class Caretaker {
    Memento memento;  
    
    public Memento getMemento() {  
        return this.memento;  
    }  
  
    public void setMemento(Memento memento) {  
        this.memento = memento;  
    }

Client.java

* 利用者(メイン)
public class Client {
    public static void main(String[] args) {
        // オブジェクトを生成する  
        Originator original = new Originator();  
        // オブジェクトの状態を設定する
        original.countParam1(1); 
        original.appendParam2("aaa");
        System.out.println("Original value : " + original.getParam1() + ", " + original.getParam2() + ".");  
  
        // Mementoを取る(今の状態を記憶する)  
        Memento snapshot = original.createMemento();  
        // CaretakerでMementoオブジェクトを保持する  
        Caretaker caretaker = new Caretaker();  
        caretaker.setMemento(snapshot);  
  
        // その他操作  
        original.countParam1(3);
        original.countParam1(4);
        original.appendParam2("bbb");  
        original.appendParam2("ccc");  
        System.out.println("Updated value : " + original.getParam1() + ", " + original.getParam2() + ".");  
  
          
        // Mementoによって復元する  
        original.restoreMemento(caretaker.getMemento());  
        System.out.println("Restored value : " + original.getParam1() + ", " + original.getParam2() + ".");  
    }  
}

出力結果

Original value : 1, aaa.
Updated value : 8, aaabbbccc.
Restored value : 1, aaa.