概要
Memento(メメント)パターンは、
あるオブジェクトの内部状態を外部から安全に記録・復元できるようにする設計パターンである。
特にUndo/Redo機能や、一時的な状態保持とロールバック処理に適しており、状態管理の柔軟性を構造化するのに役立つ。
1. なぜMementoが必要か?
❌ 状態をグローバル変数やdictなどでベタ保存
backup = {
"text": editor.text,
"cursor": editor.cursor
}
→ カプセル化を破壊し、変更に弱い構造
✅ 状態をMementoとしてオブジェクト化・隠蔽して記録
snapshot = editor.save()
...
editor.restore(snapshot)
→ 内部状態を安全に保持し、構造的に復元可能
2. 基本構造
✅ Originator(状態を持つオブジェクト)
class Editor:
def __init__(self):
self._text = ""
self._cursor = 0
def write(self, text):
self._text += text
self._cursor = len(self._text)
def save(self):
return Memento(self._text, self._cursor)
def restore(self, memento):
self._text = memento.text
self._cursor = memento.cursor
def show(self):
print(f"[Editor] '{self._text}' | cursor at {self._cursor}")
✅ Memento(状態を保存するクラス)
class Memento:
def __init__(self, text, cursor):
self.text = text
self.cursor = cursor
✅ Caretaker(履歴管理者)
class History:
def __init__(self):
self._snapshots = []
def backup(self, memento):
self._snapshots.append(memento)
def undo(self):
if self._snapshots:
return self._snapshots.pop()
return None
✅ 使用例
editor = Editor()
history = History()
editor.write("Hello")
history.backup(editor.save())
editor.write(", World!")
editor.show() # Hello, World!
editor.restore(history.undo())
editor.show() # Hello
出力:
[Editor] 'Hello, World!' | cursor at 13
[Editor] 'Hello' | cursor at 5
3. Python的応用:Mementoをdeepcopyで代用する実用例
import copy
history = []
editor = Editor()
editor.write("A")
history.append(copy.deepcopy(editor))
editor.write("B")
history.append(copy.deepcopy(editor))
editor = history[-2]
editor.show() # A
→ 小規模アプリなら deepcopy によるスナップショットでも有効
4. 実務ユースケース
✅ Undo/Redo 機能の実装(エディタ、フォーム、設定画面)
→ 操作の履歴を構造化された状態で保持し、任意のタイミングで戻す
✅ 安全なロールバック処理(DB/設定変更/ユーザー操作)
→ 設定前の状態を保持しておき、異常時に復元可能
✅ オブジェクトの一時的スナップショット保存
→ テストや一時保存、比較検証などに活用
✅ タイムトラベル型UIの実装
→ アプリケーションの状態遷移を時間軸で記録・再生
5. よくある誤用と対策
❌ Mementoが内部構造を公開してしまう
→ ✅ 読み取り専用属性とし、直接操作を避ける
❌ 状態復元の副作用が大きすぎる
→ ✅ 復元時の処理が明確に定義されていることを保証
❌ 履歴管理(Caretaker)が肥大化・不整合
→ ✅ 履歴の最大数、メモリ制限、整合性検証を事前に設計
結語
Mementoパターンとは、“過去の状態を密やかに封じ込め、未来の柔軟性を担保する設計”である。
- オブジェクトの内部状態を安全・構造的に保存・復元可能
- Undo/Redo、ロールバック、履歴管理など、時系列的状態制御の基盤を提供
- Pythonではクラスの柔軟性と動的属性によって、直感的かつ安全にMementoが構築可能
Pythonicとは、“状態の変化を設計的に制御すること”。
Mementoパターンはその制御を、スナップショットという静かな記憶に委ねる技法である。