コンテンツにスキップ
Wikipedia

Memento パターン

出典: フリー百科事典『ウィキペディア(Wikipedia)』

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

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

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

Memento パターンの例

[編集 ]

Java

[編集 ]

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

importjava.util.*;

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

publicvoidset(Stringstate){
System.out.println("Originator: Setting state to "+state);
this.state=state;
}

publicObjectsaveToMemento(){
System.out.println("Originator: Saving to Memento.");
returnnewMemento(state);
}
publicvoidrestoreFromMemento(Objectm){
if(minstanceofMemento){
Mementomemento=(Memento)m;
state=memento.getSavedState();
System.out.println("Originator: State after restoring from Memento: "+state);
}
}

privatestaticclass Memento{
privateStringstate;

publicMemento(StringstateToSave){state=stateToSave;}
publicStringgetSavedState(){returnstate;}
}
}

class Caretaker{
privateList<Object>savedStates=newArrayList<Object>();

publicvoidaddMemento(Objectm){savedStates.add(m);}
publicObjectgetMemento(intindex){returnsavedStates.get(index);}
}

class MementoExample{
publicstaticvoidmain(String[]args){
Caretakercaretaker=newCaretaker();

Originatororiginator=newOriginator();
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'
classOriginator
classMemento
definitialize(state)
# Originator の元の状態を壊しても、この Memento オブジェクトが初回以降の restore で
# 破壊されないよう dup が必要
@state=state.dup
end

defstate
# Originator の元の状態を壊しても、この Memento オブジェクトが二度目の restore で
# 破壊されないよう dup が必要
@state.dup
end
end
attr_accessor:state
# メモリに巨大なデータが多数あり、state から再構成可能であるように見せる
defsave_to_memento
Memento.new(@state)
end
defrestore_from_memento(m)
@state=m.state
end
end
classCaretaker<Array;end
describeOriginatordo
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

関連項目

[編集 ]

外部リンク

[編集 ]
GoFによる23種のパターン
生成に関するパターン
構造に関するパターン
振る舞いに関するパターン
並行性に関するパターン
アーキテクチャに関するパターン
その他のパターン
関連する人々
関連項目

AltStyle によって変換されたページ (->オリジナル) /