1
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?

【デザインパターン】メメントパターン解説

Last updated at Posted at 2025-09-12

1. パターンの意図

メメント(Memento)パターン は、
オブジェクトの状態を保存し、後で復元できるようにする デザインパターンです。

解決する問題

  • ゲームの「セーブ/ロード」のように、ある時点の状態を戻したい
  • Undo / Redo 機能を実装したい
  • 内部状態をカプセル化したまま保存・復元したい

ポイント

  • Originator:状態を持つオブジェクト。スナップショットを作成/復元する
  • Memento:保存される状態(外部から中身は見えない)
  • Caretaker:Memento を管理し、必要に応じて復元を依頼する

2. UML 図


3. Flutter / Dart 実装例

Memento

class Memento {
  final String state;
  Memento(this.state);
}

Originator

class Originator {
  String _state = '';

  void setState(String state) {
    print(" Setting state to $state");
    _state = state;
  }

  String getState() => _state;

  Memento save() => Memento(_state);

  void restore(Memento memento) {
    _state = memento.state;
    print("State restored to $_state");
  }
}

Caretaker

class Caretaker {
  final List<Memento> _history = [];

  void addMemento(Memento memento) => _history.add(memento);

  Memento? getMemento(int index) {
    if (index < 0) {
      return null;
    }
    if (_history.length > index) {
      return _history[index];
    }
    return null;
  }
}

利用例

void main() {
  var originator = Originator();
  var caretaker = Caretaker();

  originator.setState("State 1");
  caretaker.addMemento(originator.save());

  originator.setState("State 2");
  caretaker.addMemento(originator.save());

  originator.setState("State 3");

  originator.restore(caretaker.getMemento(0)); // State 1 に戻る
}

4. Android / Kotlin 実装例

Memento

data class Memento(val state: String)

Originator

class Originator {
    private var state: String = ""

    fun setState(state: String) {
        println("Setting state to $state")
        this.state = state
    }

    fun getState(): String = state

    fun save(): Memento = Memento(state)

    fun restore(memento: Memento) {
        state = memento.state
        println("State restored to $state")
    }
}

Caretaker

class Caretaker {
    private val history = mutableListOf<Memento>()

    fun addMemento(m: Memento) = history.add(m)
    fun getMemento(index: Int): Memento?{
        if(index<0){
            return null;
        }
        if(history.size<=index){
            return null;
        }
        return history[index]
    }
}

利用例

fun main() {
    val originator = Originator()
    val caretaker = Caretaker()

    originator.setState("State 1")
    caretaker.addMemento(originator.save())

    originator.setState("State 2")
    caretaker.addMemento(originator.save())

    originator.setState("State 3")

    val memento=caretaker.getMemento(0)
	if(memento!=null){
        originator.restore(memento)// State 1 に戻る
    }
}

5. 実務ユースケース

  • テキストエディタの Undo / Redo
  • 画面フォーム入力のスナップショット保存
  • ゲームのセーブ/ロード
  • IDE やエディタの Undo/Redo
  • アプリの状態管理(フォーム、画面遷移)
  • DB トランザクションのロールバック

6. メリット / デメリット

メリット

  • 状態を保存・復元できる
  • 内部構造を外部に公開せずにスナップショット可能
  • Undo/Redo やセーブ機能に適用しやすい

デメリット

  • 状態を大量に保存するとメモリ消費が大きい
  • 状態管理ロジックが複雑化することもある

まとめ

  • Memento パターンは「状態を保存し、後で復元できる仕組み」
  • Flutter/Android では Undo/Redo・セーブ/ロード・トランザクションに応用できる
  • Command = 操作の履歴 / Memento = 状態の履歴 と整理すると理解しやすい

1
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
1
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?