備忘錄 (Memento)

★★★★★Studied

FromDesign Patterns (GoF)大話設計模式

📚 From the Books

備忘錄 (Memento)ConceptBehavioral

在不破壞封裝的前提下,擷取並對外保存一個物件的內部狀態,之後可以把它還原回去。負責保管的人(caretaker)只持有快照、不去看裡面的內容。

🧠 When to Use

TIP

訊號:你想做「存檔/回復」或 undo,但又不想把物件的私有欄位全都開成 public 讓外面亂存亂取。

⚖️ Structure & Variants

經典版 — Originator 自己產生/吃回快照
class Editor(var text: String = "") {
    fun save(): Memento = Memento(text)          // 只有 Editor 看得懂內容
    fun restore(m: Memento) { text = m.state }
    class Memento(val state: String)             // 對外不透明的快照
}

val ed = Editor("hello")
val snap = ed.save()        // caretaker 拿著 snap,但不解讀它
ed.text = "world"
ed.restore(snap)            // 回到 "hello"
  • Memento 的內容只有 Editor 該理解;caretaker 只負責保管與遞回。
搭 Command 做 undo 堆疊
  • 每個 Command 執行前先向 originator 取一個 memento 壓進堆疊。
  • undo 時彈出最上面的 memento 還原;這是文字編輯器、繪圖工具最常見的組合。
封裝的取捨 — 寬介面 vs 窄介面
  • originator 提供寬介面(能讀寫快照全部欄位);對 caretaker 只露窄介面(拿得到、傳得回,看不到內容)。
  • 巢狀類別、internal/friend 機制都是用來維持「只有 originator 看得懂 memento」的手段。

⚠️ Misuse & Anti-patterns

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading