Memento patternとは? わかりやすく解説

Weblio 辞書 > 辞書・百科事典 > 百科事典 > Memento patternの意味・解説 

Memento パターン

(Memento pattern から転送)

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/11/04 16:39 UTC 版)

memento パターン: Memento pattern、日本: メメント パターン)はソフトウェアのデザインパターンの一つで、オブジェクトを以前の状態に(ロールバックにより)戻す能力を提供する。

memento パターンは二つのオブジェクトによって用いられる。'originator'と'caretaker' である。'originator' は内部状態を持つオブジェクトである。caretaker は originator に何らかの操作を行うが、その操作の結果を元に戻す機能を持たせたいとする。まず caretaker は操作を行う前に、originator へ現状の memento を要求して得る。その後、任意の操作を行う。操作前の状態に復元するには、先程 得た memento を originator に渡す。memento 自体は、不透明オブジェクト( caretaker が変更してはいけないもの) である。このパターンを使う場合、originator が他のオブジェクトやリソースを変更してしまうかどうか注意が要る。memento パターンは単一のオブジェクトに対して働くためである。

memento パターンの古典的な例として、擬似乱数発生器や、有限オートマトンの状態などがある。

Memento パターンの例

Java

以下の Java プログラムは、 Memento パターンを "undo" に使った場合を示す。

import java.util.*; 
 
class Originator {
    private String state;
    /* メモリを消費する多数の private のデータで状態に関係しないものは保存されるべきでない。
     * memento は小さなオブジェクトであるべき */

 
    public void set(String state) { 
        System.out.println("Originator: Setting state to "+state);
        this.state = state; 
    }
 
    public Object saveToMemento() { 
        System.out.println("Originator: Saving to Memento.");
        return new Memento(state); 
    }
    public void restoreFromMemento(Object m) {
        if (m instanceof Memento) {
            Memento memento = (Memento)m; 
            state = memento.getSavedState(); 
            System.out.println("Originator: State after restoring from Memento: "+state);
        }
    }
 
    private static class Memento {
        private String state;
 
        public Memento(String stateToSave) { state = stateToSave; }
        public String getSavedState() { return state; }
    }
}
 
class Caretaker {
    private List<Object> savedStates = new ArrayList<Object>();
 
    public void addMemento(Object m) { savedStates.add(m); }
    public Object getMemento(int index) { return savedStates.get(index); }
} 
 
class MementoExample {
    public static void main(String[] args) {
        Caretaker caretaker = new Caretaker();
 
        Originator originator = new Originator();
        originator.set("State1");
        originator.set("State2");
        caretaker.addMemento( originator.saveToMemento() );
        originator.set("State3");
        caretaker.addMemento( originator.saveToMemento() );
        originator.set("State4");
 
        originator.restoreFromMemento( caretaker.getMemento(1) );
    }
}

出力:

Originator: Setting state to State1
Originator: Setting state to State2
Originator: Saving to Memento.
Originator: Setting state to State3
Originator: Saving to Memento.
Originator: Setting state to State4
Originator: State after restoring from Memento: State3

Ruby

以下の Ruby プログラムで同じパターンを示す。

#!/usr/bin/env ruby -KU

require 'rubygems'
require 'spec'

class Originator
  class Memento
    def initialize(state)
      # Originator の元の状態を壊しても、この Memento オブジェクトが初回以降の restore で
      # 破壊されないよう dup が必要
      @state = state.dup
    end
    
    def state
      # Originator の元の状態を壊しても、この Memento オブジェクトが二度目の restore で
      # 破壊されないよう dup が必要
      @state.dup
    end
  end

  attr_accessor :state

  # メモリに巨大なデータが多数あり、state から再構成可能であるように見せる
  def save_to_memento
    Memento.new(@state)
  end

  def restore_from_memento(m)
    @state = m.state
  end

end

class Caretaker < Array; end

describe Originator do
  before(:all) do
    @caretaker = Caretaker.new
    @originator = Originator.new

    @originator.state = "State1"
  end

  it "should have original state" do
    @originator.state.should == 'State1'
  end

  it "should update state" do
    @originator.state = "State2"
    @originator.state.should == 'State2'
  end

  it "should save memento" do
    @caretaker << @originator.save_to_memento
    @caretaker.size.should == 1
  end

  it "should update state after save to memento" do
    @originator.state = "State3"
    @originator.state.should == 'State3'
  end

  it "should save to memento again" do
    @caretaker << @originator.save_to_memento
    @caretaker.size.should == 2
  end

  it "should update state after save to memento again" do
    @originator.state = "State4";
    @originator.state.should == 'State4'
  end

  it "should restore to original save point" do
    @originator.restore_from_memento @caretaker[0]
    @originator.state.should == 'State2'
  end

  it "should restore to second save point" do
    @originator.restore_from_memento @caretaker[1]
    @originator.state.should == 'State3'
  end

  it "should restore after pathological munging of restored state" do
    @originator.state[-1] = '5'
    @originator.state.should == 'State5'
    @originator.restore_from_memento @caretaker[1]
    @originator.state.should == 'State3'
  end
  
  it "should restore after pathological munging of original state" do
    @originator.state = "State6"
    @originator.state.should == 'State6'
    @caretaker << @originator.save_to_memento
    @originator.state[-1] = '7'
    @originator.state.should == 'State7'
    @originator.restore_from_memento @caretaker[2]
    @originator.state.should == 'State6'
  end
end

関連項目

外部リンク




英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「Memento pattern」の関連用語

Memento patternのお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



Memento patternのページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアのMemento パターン (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。

©2025 GRAS Group, Inc.RSS