後端開發 設計模式 · 第 19 / 24 篇

備忘錄模式:保存與恢復物件狀態

備忘錄模式 (Memento Pattern) 讓你能隨時保存並恢復物件狀態。本文透過 C# 遊戲存檔範例,教你如何實作狀態回復機制。

哈囉朋友們!今天我們要介紹的是一個超實用的設計模式:備忘錄模式(Memento),透過它,我們可以輕鬆儲存並回復物件的狀態!

🌟 備忘錄模式是什麼?

備忘錄模式允許你捕捉一個物件的內部狀態,並且在未來需要時,能夠將物件回復到原先的狀態。

就像玩遊戲時的「存檔」和「讀取進度」功能一樣,當你不小心走錯路或失敗時,可以輕鬆回到之前的狀態重新來過。


🤔 什麼情況適合使用備忘錄模式?

當你有以下情境時,很適合使用備忘錄模式:

  • 需要提供撤銷(undo)或回復(redo)操作。
  • 物件狀態可能頻繁改變,且希望能隨時回到某個特定的狀態。
  • 不想暴露物件內部狀態的細節給外部使用者。

🎮 C# 備忘錄模式範例:遊戲存檔系統

我們透過「遊戲角色存檔」來說明備忘錄模式的應用。

🎲 建立備忘錄(Memento)

/// <summary>
/// 遊戲狀態備忘錄
/// </summary>
public class GameMemento
{
    /// <summary>
    /// 等級
    /// </summary>
    public int Level { get; }

    /// <summary>
    /// 生命值
    /// </summary>
    public int Health { get; }

    public GameMemento(int level, int health)
    {
        Level = level;
        Health = health;
    }
}

🧙 遊戲角色(Originator)

using System;

/// <summary>
/// 遊戲角色
/// </summary>
public class GameCharacter
{
    /// <summary>
    /// 等級
    /// </summary>
    public int Level { get; set; }

    /// <summary>
    /// 生命值
    /// </summary>
    public int Health { get; set; }

    /// <summary>
    /// 顯示目前狀態
    /// </summary>
    public void DisplayStatus()
    {
        Console.WriteLine($"目前狀態 => 等級:{Level},生命值:{Health}");
    }

    /// <summary>
    /// 儲存目前狀態
    /// </summary>
    public GameMemento Save()
    {
        return new GameMemento(Level, Health);
    }

    /// <summary>
    /// 從備忘錄回復狀態
    /// </summary>
    public void Restore(GameMemento memento)
    {
        Level = memento.Level;
        Health = memento.Health;
    }
}

📔 存檔管理員(Caretaker)

/// <summary>
/// 存檔管理員
/// </summary>
public class GameCaretaker
{
    /// <summary>
    /// 目前的備忘錄
    /// </summary>
    public GameMemento Memento { get; set; }
}

🚀 實際使用範例

using System;

class Program
{
    static void Main(string[] args)
    {
        GameCharacter hero = new GameCharacter { Level = 10, Health = 100 };
        hero.DisplayStatus();

        // 存檔
        GameCaretaker caretaker = new GameCaretaker();
        caretaker.Memento = hero.Save();

        // 角色狀態改變
        hero.Level = 12;
        hero.Health = 50;
        hero.DisplayStatus();

        // 讀取存檔
        hero.Restore(caretaker.Memento);
        hero.DisplayStatus();
    }
}

🎯 執行結果

目前狀態 => 等級:10,生命值:100
目前狀態 => 等級:12,生命值:50
目前狀態 => 等級:10,生命值:100

⚠️ 備忘錄模式使用注意事項

  • 優點:能有效支援狀態回復和撤銷,並且不暴露內部細節。
  • 缺點:當保存狀態過多時,可能占用大量記憶體。

🎉 結語

恭喜你掌握了備忘錄模式(Memento)!透過這個模式,你的程式可以輕鬆管理物件的歷史狀態,讓用戶體驗更順暢!

持續追蹤我們的設計模式系列喔,下篇再見啦~

系列:

讀完了!你覺得這篇如何?

你的回饋會決定下一篇要寫什麼。

還有疑問

Learning path

設計模式

這篇是系列中的第 19 / 24 篇。可以順著列表補完整脈絡,也可以直接跳到需要的段落。

  1. 01 搞懂設計模式到底是什麼?
  2. 02 單例模式:只要一個就夠!
  3. 03 工廠方法模式:點披薩不用親自下廚
  4. 04 抽象工廠模式:系列產品輕鬆生產
  5. 05 原型模式:複製的藝術
  6. 06 建造者模式:一步步完成複雜任務
  7. 07 介面卡模式:讓不相容也能合作
  8. 08 橋接模式:抽象與實作分離
  9. 09 組合模式:樹狀結構的好幫手
  10. 10 裝飾者模式:讓功能自由加點
  11. 11 外觀模式:化繁為簡
  12. 12 享元模式:節省記憶體的利器
  13. 13 代理模式:控制存取的守門員
  14. 14 責任鏈模式:層層把關的處理機制
  15. 15 命令模式:靈活封裝的請求指令
  16. 16 解譯器模式:讓程式聽懂你的指令
  17. 17 迭代器模式:輕鬆遍歷集合元素
  18. 18 中介者模式:管理複雜溝通的好幫手
  19. 19 備忘錄模式:保存與恢復物件狀態 目前閱讀
  20. 20 觀察者模式:即時通知的好幫手
  21. 21 狀態模式:依狀態改變行為的祕訣
  22. 22 策略模式:靈活切換行為的好幫手
  23. 23 模板方法模式:固定流程靈活實作
  24. 24 訪問者模式:新增功能不動既有架構

Further reading

中介者模式:管理複雜溝通的好幫手 封面圖 2025-06-13 中介者模式:管理複雜溝通的好幫手 模板方法模式:固定流程靈活實作 封面圖 2025-06-13 模板方法模式:固定流程靈活實作 狀態模式:依狀態改變行為的祕訣 封面圖 2025-06-13 狀態模式:依狀態改變行為的祕訣

留言討論

用 GitHub 帳號留言,留言會同步到這個 Blog 的 GitHub Discussions。

閱讀導覽

約 2 分鐘

本篇所在系列 · 第 19 / 24 篇

設計模式

  1. 搞懂設計模式到底是什麼?
  2. 單例模式:只要一個就夠!
  3. 工廠方法模式:點披薩不用親自下廚
  4. 抽象工廠模式:系列產品輕鬆生產
  5. 原型模式:複製的藝術
  6. 建造者模式:一步步完成複雜任務
  7. 介面卡模式:讓不相容也能合作
  8. 橋接模式:抽象與實作分離
  9. 組合模式:樹狀結構的好幫手
  10. 裝飾者模式:讓功能自由加點
  11. 外觀模式:化繁為簡
  12. 享元模式:節省記憶體的利器
  13. 代理模式:控制存取的守門員
  14. 責任鏈模式:層層把關的處理機制
  15. 命令模式:靈活封裝的請求指令
  16. 解譯器模式:讓程式聽懂你的指令
  17. 迭代器模式:輕鬆遍歷集合元素
  18. 中介者模式:管理複雜溝通的好幫手
  19. 備忘錄模式:保存與恢復物件狀態
  20. 觀察者模式:即時通知的好幫手
  21. 狀態模式:依狀態改變行為的祕訣
  22. 策略模式:靈活切換行為的好幫手
  23. 模板方法模式:固定流程靈活實作
  24. 訪問者模式:新增功能不動既有架構
看完整系列 24 篇