首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

深入淺出 Java 設計模式:備忘錄模式完整實作與封裝性保護策略

     編輯:Java 程式設計入門

模式動機:程式世界的「後悔藥」

備忘錄模式在不破壞封裝前提下,捕捉物件內部狀態並外部化儲存,支援後續恢復。常用於 Undo/Redo、交易回滾、棋局悔棋等場景。核心三角色:

  • Originator(發起人):建立備忘錄、從備忘錄恢復狀態。
  • Memento(備忘錄):儲存發起人內部狀態,提供窄/寬介面隔離存取權限。
  • Caretaker(管理者):負責保管備忘錄,不可檢視或修改內容。

Java 中的封裝性挑戰

GoF 原書以 C++ friend 實現「發起人可見備忘錄細節、管理者僅見窄介面」。Java 無 friend 機制,需替代方案:

方案一:雙介面隔離(輕量但依賴自律)

  • MementoIF(窄介面):標記介面,管理者僅持有此型別參考。
  • MementoWideIF(寬介面):含 getState() 等方法,發起人轉型後存取。
  • 缺點:編譯期無法強制阻止管理者強制轉型。

方案二:私有內部類(推薦,編譯期強制封裝)

public class Originator {
    private int state = 90;
    private Caretaker caretaker = new Caretaker();

    // 發起人對外 API
    public void createMemento() { caretaker.saveMemento(new Memento(state)); }
    public void setMemento() {
        Memento m = (Memento) caretaker.getMemento();
        state = m.getState();
    }

    // 私有內部類:外部完全不可見
    private class Memento implements MementoIF {
        private final int state;
        private Memento(int state) { this.state = state; }
        private int getState() { return state; }
    }
}

// 窄介面
interface MementoIF {}

// 管理者:只能操作 MementoIF
class Caretaker {
    private MementoIF m;
    void saveMemento(MementoIF m) { this.m = m; }
    MementoIF getMemento() { return m; }
}

優點:Memento 為 private,外部連類別名稱都不可見,徹底封裝。發起人同時扮演 Facade 簡化用戶端呼叫。

方案三:Clone 模式(不推薦)

讓發起人實作 Cloneable,備忘錄直接用 clone() 複製。缺點:淺拷貝風險、破壞封裝(需公開 clone())、無法精確控制備份範圍。

實戰應用場景

  • 文字編輯器 Undo/Redo(儲存文檔快照)
  • 資料庫交易回滾點
  • 遊戲存檔/讀檔
  • Wizard 精靈式介面的上一步/下一步

備忘錄模式的精髓在於「狀態外部化且不破壞封裝」,Java 開發者應優先採用私有內部類方案,兼顧型別安全與封裝純度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved