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
関連項目
[編集 ]外部リンク
[編集 ]- Description by Matthew Heaney
- Memento UML Class Diagram with C# and .NET code samples
GoFによる23種のパターン |
| ||||||
---|---|---|---|---|---|---|---|
並行性に関するパターン | |||||||
アーキテクチャに関するパターン | |||||||
その他のパターン |
| ||||||
関連する人々 | |||||||
関連項目 | |||||||