導入
GoFの締めくくり。Visitorは「データ構造を変えずに新しい操作を追加」、Interpreterは「独自の文法を解釈・評価」、Mementoは「状態を保存して後で復元(Undo)」します。
図解
flowchart LR
S1["状態1"] -->|保存| M["Memento(スナップショット)"]
S2["状態2(変更後)"] -->|Undo| M
M -->|復元| S1
サンプル
// Memento: 状態を保存し、後で復元(Undo)する
var editor = new TextEditor();
editor.Type("こんにちは");
var saved = editor.Save(); // スナップショットを取る
editor.Type("(削除される)");
editor.Restore(saved); // 保存時点に戻す
Console.WriteLine(editor.Text); // こんにちは
// Interpreter: 独自の簡単な式 "3 + 4" を解釈して評価
Console.WriteLine(Evaluate("3 + 4")); // 7
class TextEditor
{
public string Text { get; private set; } = "";
public void Type(string s) => Text += s;
public string Save() => Text; // Memento(状態の複製)
public void Restore(string memento) => Text = memento;
}
int Evaluate(string expr)
{
var parts = expr.Split(' ');
int a = int.Parse(parts[0]);
int b = int.Parse(parts[2]);
return parts[1] == "+" ? a + b : a - b;
}
- Visitor: 要素側に「訪問者を受け入れる口」を作り、操作を外部クラス(訪問者)に追加できる
- Interpreter: 独自の文法(式・ルール)を表現し評価する(電卓・クエリ言語等)
- Memento: 内部状態のスナップショットを保存し、Undo/やり直しを実現する
演習
var game = new Game();
game.Score = 100;
var checkpoint = game.Save();
game.Score = 999;
game.Restore(checkpoint);
Console.WriteLine(game.Score); // 100
// TODO: Score を Save() で保存し Restore() で復元できる Game クラスを定義してください
___
- 期待される出力:
100
ヒント1を見る
Saveは現在のScoreを返し、Restoreは受け取った値をScoreに戻します
ヒント2を見る
class Game { public int Score; public int Save() => Score; public void Restore(int m) => Score = m; }
まとめ
- Visitorはデータ構造を変えず操作を追加する
- Interpreterは独自文法を解釈・評価する
- Mementoは状態を保存し復元(Undo)する
次回: 23パターンの実践的な使い分けを整理します。