0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonで実装するMementoパターン:オブジェクトの状態をスナップショットとして保存・復元する

Posted at

概要

Memento(メメント)パターンは、
オブジェクトの内部状態を外部に公開することなく、状態のスナップショットを保存・復元できる設計パターンである。

「Undo/Redo機能」や「タイムトラベルデバッグ」、「状態復元」のような操作に最適で、可逆的な操作を可能にする


1. なぜMementoが必要か?

❌ 現在の状態を上書きするだけでは、過去に戻れない

text.set("新しいテキスト")  # 前の状態は消えてしまう

履歴を管理しないと取り消しができない


✅ 状態をMementoとして保存すれば、復元が可能になる

history.append(text.save())
...
text.restore(history.pop())

状態を「保存・復元」できる構造で、安全にUndoが実現


2. 基本構造

✅ Memento(スナップショット)

class Memento:
    def __init__(self, state):
        self._state = state

    def get_state(self):
        return self._state

✅ Originator(状態を持つ本体)

class TextEditor:
    def __init__(self):
        self._content = ""

    def write(self, text):
        self._content += text

    def show(self):
        print(self._content)

    def save(self):
        return Memento(self._content)

    def restore(self, memento: Memento):
        self._content = memento.get_state()

✅ Caretaker(Mementoの管理者)

class History:
    def __init__(self):
        self._stack = []

    def push(self, memento):
        self._stack.append(memento)

    def pop(self):
        return self._stack.pop() if self._stack else None

✅ 使用例

editor = TextEditor()
history = History()

editor.write("Hello, ")
history.push(editor.save())

editor.write("World!")
editor.show()  # Hello, World!

editor.restore(history.pop())
editor.show()  # Hello,

3. Python的応用:状態スナップショットをdictで表現する

class Counter:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1

    def snapshot(self):
        return {"count": self.count}

    def restore(self, snap):
        self.count = snap["count"]

辞書やJSON形式で状態をスナップショット化することで汎用性が高まる


4. 実務ユースケース

✅ テキストエディタのUndo/Redo

操作前の状態を保存しておき、Undoで復元


✅ グラフィックソフトの履歴機能(Photoshop等)

状態スナップショットによる柔軟なタイムトラベル


✅ テスト中の状態退避(前後比較・巻き戻し)

→ ある処理の開始時点の状態を記録し、復元テストに活用


✅ ゲームにおけるセーブポイントや巻き戻し機能

ゲーム進行の断面を保存・復元するメカニズム


5. よくある誤用と対策

❌ Mementoが状態を丸ごと持ちすぎて重い

→ ✅ 最小限の差分・変更のみをスナップショットにする


❌ OriginatorがMementoの内部構造を操作してしまう

→ ✅ Mementoは読み取り専用とし、カプセル化を守る


❌ Mementoの履歴が膨張しメモリを圧迫

→ ✅ 保存上限・差分保存・圧縮などの最適化が必要


結語

Mementoパターンとは、“過去の状態を封じ込め、未来で取り出せる設計”である。

  • 状態の保存と復元を構造化し、安全なUndo/Redoを実現
  • 内部情報をカプセル化したまま、タイムトラベルを可能にする
  • Pythonではオブジェクトや辞書・JSONなどで、柔軟に表現可能

Pythonicとは、“変化を記録し、巻き戻し可能にする知性”。
Mementoパターンはその知性を、記憶という構造で静かに包む技法である。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?