メメントパターンは、ソフトウェア開発におけるデザインパターンの一つで、オブジェクトの状態を以前の状態にロールバックする機能を提供するものです。このパターンは、主に「オリジネータ」と「ケアテイカー」という2つのオブジェクトによって実現されます。
パターンの構成要素
1.
オリジネータ (Originator): 内部状態を持つオブジェクトで、この状態が変更される可能性があります。オリジネータは、自身の状態を保存するための「メメント」を作成する責任を持ちます。また、メメントから以前の状態を復元する機能も持ちます。
2.
ケアテイカー (Caretaker): オリジネータに対して操作を行うオブジェクトです。ケアテイカーは、操作前にオリジネータにメメントの作成を依頼し、そのメメントを保持します。必要に応じて、保持しているメメントを使用してオリジネータの状態を復元します。ケアテイカーは、メメントの内容には関与せず、単に保管と復元を行う役割を担います。
3.
メメント (Memento): オリジネータの内部状態をカプセル化したオブジェクトです。ケアテイカーはメメントの中身を知る必要はなく、メメントを操作することもできません。これにより、オリジネータの状態を安全に保存・復元できます。メメントは不変のオブジェクトとして扱われます。
メメントパターンの動作
1. ケアテイカーはオリジネータに操作を行う前に、現在の状態を保存するためにメメントの作成を依頼します。
2. オリジネータは自身の現在の状態をメメントオブジェクトとして作成し、ケアテイカーに返します。
3. ケアテイカーはメメントを安全な場所に保管します。
4. オリジネータはケアテイカーからの操作によって状態が変更されます。
5. もし、ケアテイカーがオリジネータの状態を以前の状態に戻したい場合、保存していたメメントをオリジネータに渡します。
6. オリジネータは、受け取ったメメントの情報をもとに、自身の状態を復元します。
注意点
メメントパターンを使用する際には、オリジネータが他のオブジェクトやリソースを変更してしまう可能性に注意が必要です。メメントパターンは単一のオブジェクトの状態を扱うためのパターンであり、複数のオブジェクトの状態をまとめて管理するものではありません。
具体例
メメントパターンの具体的な例としては、以下のようなものが挙げられます。
擬似乱数発生器: 擬似乱数発生器の状態を保存し、以前の状態から乱数生成を再開する。
有限オートマトン:
有限オートマトンの状態を保存し、以前の状態に戻す。
テキストエディタのUndo機能: テキストエディタでの編集操作をメメントとして保存することで、Undo操作を実現します。
コード例
java
public class Originator {
private String state;
public void setState(String state) {
this.state = state;
System.out.println("Originator: Setting state to " + state);
}
public Memento saveToMemento() {
System.out.println("Originator: Saving to Memento.");
return new Memento(state);
}
public void restoreFromMemento(Memento memento) {
this.state = memento.getState();
System.out.println("Originator: State after restoring from Memento: " + state);
}
static class Memento {
private String state;
public Memento(String state) {
this.state = state;
}
public String getState(){
return this.state;
}
}
}
public class Caretaker {
public static void main(String[] args){
Originator originator = new Originator();
originator.setState("State1");
originator.setState("State2");
Originator.Memento memento1 = originator.saveToMemento();
originator.setState("State3");
Originator.Memento memento2 = originator.saveToMemento();
originator.setState("State4");
originator.restoreFromMemento(memento2);
}
}
ruby
class Originator
attr_accessor :state
def initialize(state)
@state = state
puts "Originator: Setting state to #{@state}"
end
def save_to_memento
puts "Originator: Saving to Memento."
Memento.new(@state)
end
def restore_from_memento(memento)
@state = memento.state
puts "Originator: State after restoring from Memento: #{@state}"
end
end
class Memento
attr_reader :state
def initialize(state)
@state = state
end
end
originator = Originator.new('State1')
originator.state = 'State2'
memento1 = originator.save_to_memento
originator.state = 'State3'
memento2 = originator.save_to_memento
originator.state = 'State4'
originator.restore_from_memento(memento2)
関連パターン
Facadeパターン: 複雑なシステムを隠蔽し、シンプルなインターフェースを提供するパターン。
永続データ構造: 変更しても以前のバージョンを保持するデータ構造。
外部リンク
Description by Matthew Heaney
*
Memento UML Class Diagram with C# and .NET code samples
これらの情報が、メメントパターンの理解に役立つことを願っています。