メメントパターン
メメントパターン(Memento Pattern) は、オブジェクトの状態を保存し、後でその状態を復元できるようにするデザインパターンです。このパターンを使うことで、オブジェクトの内部状態をキャプチャし、必要に応じてその状態に戻すことが可能になります。元のオブジェクトの状態を隠蔽しながら、安全に保存および復元することを目的としています。
メメントパターンは、「アンドゥ(取り消し)」機能や、アプリケーションの特定の状態を後で復元したい場合に有効です。例えば、テキストエディタのアンドゥ機能などで使用されます。
TypeScriptでのメメントパターンの実装
以下に、TypeScriptでメメントパターンを実装する例を紹介します。この例では、テキストエディタがテキストの状態を保存し、後でその状態に戻すシナリオを示します。
テキストエディタの例
typescript
// メメントクラス(保存する状態を表現)
class Memento {
private state: string;
constructor(state: string) {
this.state = state;
}
getState(): string {
return this.state;
}
}
// オリジネータークラス(状態を生成・復元する)
class TextEditor {
private text: string = '';
setText(text: string): void {
this.text = text;
}
getText(): string {
return this.text;
}
// 現在の状態を保存するメソッド
save(): Memento {
return new Memento(this.text);
}
// 保存した状態を復元するメソッド
restore(memento: Memento): void {
this.text = memento.getState();
}
}
// ケアテイカークラス(メメントを管理する)
class Caretaker {
private mementos: Memento[] = [];
addMemento(memento: Memento): void {
this.mementos.push(memento);
}
getMemento(index: number): Memento {
return this.mementos[index];
}
}
// 実際の使用例
const editor = new TextEditor();
const caretaker = new Caretaker();
// 初期のテキストを設定
editor.setText('Hello, world!');
console.log('Current Text:', editor.getText());
caretaker.addMemento(editor.save()); // 状態を保存
// テキストを変更
editor.setText('Hello, TypeScript!');
console.log('Current Text:', editor.getText());
caretaker.addMemento(editor.save()); // 状態を保存
// テキストをさらに変更
editor.setText('Hello, Design Patterns!');
console.log('Current Text:', editor.getText());
// 最初の状態に戻す
editor.restore(caretaker.getMemento(0));
console.log('Restored to:', editor.getText());
// 2番目の状態に戻す
editor.restore(caretaker.getMemento(1));
console.log('Restored to:', editor.getText());
解説
Mementoクラス(メメント)
Memento
クラスは、TextEditor
の状態を保存する役割を持ちます。このクラスは保存された状態を保持し、外部にその状態を公開するためのgetState
メソッドを提供します。
TextEditorクラス(オリジネーター)
TextEditor
クラスは、編集されるテキストを管理するクラスです。このクラスはsave
メソッドで現在のテキストの状態をMemento
として保存し、restore
メソッドで保存された状態を復元します。
Caretakerクラス(ケアテイカー)
Caretaker
クラスは、メメントを管理する役割を持ちます。addMemento
メソッドでMemento
を保存し、getMemento
メソッドで保存されたMemento
を取り出して復元に使用します。
実際の使用例
TextEditor
インスタンスを使ってテキストを編集し、Caretaker
を通じて状態を保存します。状態を変更した後、保存しておいたメメントを使って、以前の状態に復元することができます。
利点
- 状態の保存と復元: オブジェクトの状態を保存し、後で簡単にその状態に戻すことができます。これにより、例えばアンドゥ/リドゥの操作を簡単に実装できます。
- 内部状態の隠蔽: オブジェクトの内部状態を直接外部に公開することなく、安全に状態を保存および復元できます。
- 柔軟な状態管理: オブジェクトの状態を複数のタイミングで保存し、必要に応じて任意の状態に戻せるため、柔軟に状態を管理できます。
使用例
- テキストエディタ: テキストエディタなどのアプリケーションで、編集内容を保存し、ユーザーがアンドゥ/リドゥを行えるようにする場合に使われます。
- ゲームの進行状況: ゲームのプレイヤーの進行状況を保存し、後でその状態に戻すことで、チェックポイントやセーブポイントの機能を実現します。
- 設定のバックアップと復元: 設定変更前に状態を保存し、変更後に問題があれば元の設定に戻すために使用します。
まとめ
メメントパターンは、オブジェクトの状態を安全に保存し、必要に応じてその状態を復元するためのデザインパターンです。TypeScriptでの実装を通じて、オブジェクトの内部状態を隠蔽しながら保存・復元する仕組みを理解することができました。
このパターンを利用することで、アンドゥ機能や状態のバックアップと復元といった機能を簡単に実装することが可能になり、アプリケーションのユーザー体験を向上させることができます。