設計模式:Memento 模式詳解

Memento 模式詳解

Memento(備忘錄)模式是一種行為型設計模式,用于在不破壞封裝性的前提下,捕獲并外部化一個對象的內部狀態,以便在之后能夠將該對象恢復到原先保存的狀態。它廣泛應用于需要實現撤銷(Undo)、回滾、歷史記錄、快照機制等場景,如文本編輯器、圖形設計工具、游戲存檔系統、事務管理與配置回退。該模式通過將狀態的保存與恢復職責分離,保護了對象的封裝性,避免了將內部狀態暴露給外部調用者,是構建可維護、可恢復系統的重要技術手段。

一、Memento 模式的結構與核心角色

Memento 模式源于對“狀態保存-恢復”問題的抽象,屬于 GoF(Gang of Four)23 種經典設計模式之一。其核心思想是引入一個中間對象——備忘錄(Memento),作為原發器(Originator)狀態的容器,并由負責人(Caretaker)管理備忘錄的生命周期。該模式涉及三個關鍵角色:

  • Originator(原發器):需要被保存和恢復狀態的對象,如文檔、游戲角色或配置管理器。
  • Memento(備忘錄):存儲 Originator 內部狀態的快照對象,通常只允許 Originator 訪問其內容。
  • Caretaker(負責人):負責保存和管理 Memento 對象,但不能訪問其內部狀態。

這種職責分離確保了 Originator 的封裝性不被破壞,同時實現了狀態的歷史管理。其類結構關系如下圖所示:

creates and uses
stores and retrieves
Originator
-state: String
+setState(state)
+getState()
+saveStateToMemento()
+getStateFromMemento(Memento)
Memento
-state: String
+getState()
Caretaker
-mementoList: List<Memento>
+add(Memento)
+get(int)

Originator 創建 Memento 來保存當前狀態,Caretaker 負責存儲這些 Memento(如棧或列表),并在需要時交還給 Originator 進行恢復。

二、Memento 模式詳解

2.1 Originator(原發器)

Originator 是系統中需要支持狀態回退的核心對象。它包含業務數據和邏輯,例如一個文本編輯器中的文檔內容、一個游戲角色的生命值與位置等。Originator 提供 saveStateToMemento() 方法,用于創建一個包含當前狀態的 Memento 對象;同時提供 getStateFromMemento(Memento) 方法,用于從 Memento 中恢復狀態。關鍵在于,Memento 的構造函數通常由 Originator 調用,并傳入其私有狀態,從而保證狀態封裝性不被外部破壞。Originator 可以在狀態變化前主動保存快照,或響應外部請求進行恢復。

2.2 Memento(備忘錄)

Memento 是一個輕量級的數據載體,其主要職責是安全地保存 Originator 的內部狀態。它通常只提供一個讀取狀態的方法(如 getState()),而不允許外部修改。在強封裝要求下,Memento 的狀態字段為私有,且僅 Originator 可訪問——這可通過語言特性實現,如 Java 中的包級私有或友元類機制。Memento 本身不包含任何業務邏輯,僅作為狀態的“容器”。它可以支持序列化以便持久化存儲,或用于網絡傳輸實現遠程狀態恢復。由于 Memento 可能頻繁創建,需注意內存占用,必要時可結合對象池或壓縮機制優化。

2.3 Caretaker(負責人)

Caretaker 負責管理 Memento 的生命周期,但它不能也不應訪問 Memento 中的狀態內容。它通常將 Memento 存儲在集合中,如棧(用于實現撤銷/重做)、隊列(用于歷史記錄)或列表(用于快照管理)。Caretaker 根據操作序列調用 Originator 的保存方法獲取 Memento 并存儲;在用戶請求“撤銷”時,從集合中取出最近的 Memento 并交還給 Originator 進行恢復。Caretaker 與 Originator 解耦,使得狀態管理邏輯獨立于業務邏輯,提升了系統的模塊化程度。例如,一個通用的“命令歷史管理器”可作為 Caretaker,服務于多個不同類型的 Originator。

三、總結

以下表格對比了 Memento 模式中三個角色的職責與訪問權限:

角色職責是否可訪問 Memento 狀態典型實現方式
Originator創建、恢復狀態是(唯一可讀取者)提供 save/get 方法
Memento存儲狀態快照自身可讀,外部不可寫私有狀態 + 只讀接口
Caretaker管理 Memento 生命周期否(僅持有引用)棧、列表、隊列存儲

Memento 模式通過這種嚴格的訪問控制,實現了封裝性與可恢復性的統一。它適用于任何需要狀態快照的場景,尤其在交互式系統中價值顯著。

架構師洞見:
Memento 模式不僅是實現撤銷功能的技術工具,更是構建可觀察、可回滾、可調試系統的架構基礎。在微服務與事件溯源(Event Sourcing)架構中,其思想被進一步擴展:每個狀態變更作為事件記錄,系統可通過重放事件流恢復任意歷史狀態——這本質上是 Memento 模式的時序化與持久化演進。現代系統中,Memento 常與 Command 模式結合,形成“命令-備忘錄”對,支持多級撤銷與事務回滾。未來,隨著 AI 驅動的自動回退與異常修復需求增長,Memento 模式將向智能化、輕量化與分布式快照方向發展。架構師應重視狀態管理的設計,避免將“臨時狀態”與“持久狀態”混雜,確保系統具備良好的可恢復性與運維能力。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91164.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91164.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91164.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構(6)單鏈表算法題(下)

一、環形鏈表Ⅰ 1、題目描述 https://leetcode.cn/problems/linked-list-cycle 2、算法分析 思路&#xff1a;快慢指針 根據上圖所示的流程&#xff0c;我們可以推測出這樣一個結論&#xff1a;若鏈表帶環&#xff0c;快慢指針一定會相遇。 那么&#xff0c;這個猜測是否正…

智能制造,從工廠建模,工藝建模,柔性制造,精益制造,生產管控,庫存,質量等多方面講述智能制造的落地方案。

智能制造&#xff0c;從工廠建模&#xff0c;工藝建模&#xff0c;柔性制造&#xff0c;精益制造&#xff0c;生產管控&#xff0c;庫存&#xff0c;質量等多方面講述智能制造的落地方案。

Qt 分裂布局:QSplitter 使用指南

在 GUI 開發中&#xff0c;高效管理窗口空間是提升用戶體驗的關鍵。QSplitter 作為 Qt 的核心布局組件&#xff0c;讓動態分割窗口變得簡單直觀。一、QSplitter 核心功能解析 QSplitter 是 Qt 提供的布局管理器&#xff0c;專用于創建可調節的分割區域&#xff1a; 支持水平/垂…

R語言與作物模型(DSSAT模型)技術應用

R語言在DSSAT模型的氣候、土壤、管理措施等數據準備&#xff0c;自動化模擬和結果分析上都發揮著重要的作用。一&#xff1a;DSSAT模型的高級應用 1.作物模型的概念 2.DSSAT模型發展現狀 3.DSSAT與R語言的安裝 4.DSSAT模型的高級應用案例 5.R語言在作物模型參數優化中的應用 6.…

JavaSE:學習輸入輸出編寫簡單的程序

一、打印輸出到屏幕 Java提供了三種核心輸出方法&#xff0c;適合不同場景&#xff1a; System.out.println() 打印內容后 自動換行 System.out.println("Welcome"); System.out.println("to ISS"); // 輸出&#xff1a; // Welcome // to ISSSystem.out…

訪問者模式感悟

訪問者模式 首先有兩個東西: 一個是訪問者vistor (每一個訪問者類都代表了一類操作) 一個是被訪問者entity (model /info/pojo/node等等這些都行)也就是是說是一個實體類 其操作方法被抽離給了其他類。 訪問者模式的核心思想就是**“把操作從數據結構中分離出來,每種操作…

從零到部署:基于Go和Docker的全棧短鏈接服務實戰(含源碼)

摘要&#xff1a;本文將手把手帶你使用Go語言&#xff0c;并遵循依賴倒置、分層架構等最佳實踐&#xff0c;構建一個高性能、高可用的全棧短鏈接生成器。項目采用Echo框架、GORM、Redis、MySQL&#xff0c;并通過Docker和Docker Compose實現一鍵式容器化部署到阿里云服務器。文…

MyBatis_3

上一篇文章&#xff0c;我們學習了使用XML實現MyBatis進行增、刪、查、改等操作&#xff0c;本篇文章&#xff0c;我們將學習#{ }和${ }獲取方法參數的區別和使用MyBatisXML實現動態SQL語句。 #{ }和${ }的區別 在之前的文章中我們都是使用#{ }進行賦值&#xff0c;但實際上M…

智能圖書館管理系統開發實戰系列(一):項目架構設計與技術選型

項目背景 智能圖書館管理系統&#xff08;ILMS&#xff09;是一個現代化的桌面應用程序&#xff0c;采用前后端分離架構&#xff0c;結合了Web技術的靈活性和桌面應用的用戶體驗。本項目從高保真原型設計開始&#xff0c;經過完整的軟件開發生命周期&#xff0c;最終實現為一個…

應急前端“黃金3分鐘”設計:極端場景下的操作界面極速搭建技術

摘要**地震突發&#xff0c;應急指揮系統的操作界面卻因加載緩慢無法及時調取數據&#xff1b;火災現場&#xff0c;消防員手持終端的操作步驟繁瑣&#xff0c;延誤救援時機。在分秒必爭的極端場景中&#xff0c;傳統前端操作界面為何頻頻 “掉鏈子”&#xff1f;怎樣才能在 “…

【Android】三種彈窗 Fragment彈窗管理

三三要成為安卓糕手 零&#xff1a;布局轉換 在很多工程當中用的都是LinearLayout和relativelayout&#xff0c;這兩者都可以轉化為Constrainlayout 注&#xff1a;這種用法并不能精確轉換&#xff0c;具體還是要根據自己的需求來做布局約束一&#xff1a;snackbar顯示彈窗 ((2…

【AI繪畫】Stable Diffusion webUI 與 ComfyUI 全解析:安裝、模型、插件及功能對比

一、Stable Diffusion 與 UI 工具概述 Stable Diffusion 是當前最主流的開源 AI 繪畫模型&#xff0c;通過文本描述生成高質量圖像。為降低使用門檻&#xff0c;開發者推出了多種圖形界面&#xff08;UI&#xff09;工具&#xff0c;其中AUTOMATIC1111 webUI&#xff08;簡稱 …

ABP VNext + GraphQL Federation:跨微服務聯合 Schema 分層

ABP VNext GraphQL Federation&#xff1a;跨微服務聯合 Schema 分層 &#x1f680; 在微服務架構下&#xff0c;服務之間往往需要相互通信&#xff0c;而 GraphQL Federation 提供了一個有效的解決方案&#xff0c;幫助我們將多個微服務的 GraphQL API 聚合成一個統一的入口…

小程序組件的生命周期,以及在小程序中進行接口請求的方法設置

微信小程序組件生命周期與接口請求方法詳解一、小程序組件生命周期微信小程序組件的生命周期指的是組件在不同階段自動觸發的函數&#xff0c;開發者可以利用這些鉤子函數在特定時機執行相應操作。小程序組件的生命周期主要分為兩類&#xff1a;組件自身生命周期和組件所在頁面…

在線游戲玩家與物品交互處理

玩家與物品接觸后的判定if (hit ! null && hit.CompareTag("Item")){Debug.Log("撿東西");var worldItem hit.gameObject.GetComponent<WorldItem>();if (worldItem ! null){var inventory GetComponent<PlayerInventory>();if (inv…

深入解析Java Stream 構建:AbstractPipeline

Java Stream 宏觀介紹見&#xff1a;深入解析 Java Stream 設計&#xff1a;從四幕劇看流水線設計與執行機制-CSDN博客 PipelineHelper PipelineHelper 是 Java Stream API 內部一個至關重要的輔助類。正如其名&#xff0c;它是一個“管道助手”。可以把它想象成一個執行上下文…

《林景媚與命運回響》

《林景媚與命運回響》——當數據庫開始回響命運&#xff0c;現實是否還能被信任&#xff1f;《林景媚數據庫宇宙》系列第九部第一章&#xff1a;命運的漣漪公元 2089 年&#xff0c;數據庫神諭的運行已趨于穩定&#xff0c;PostgreSQL Quantum Engine&#xff08;PQE&#xff0…

圖神經網絡入門:從GNN開始01圖卷積網絡GCN節點分類 02圖注意力網絡GAT 03圖自編碼器GAE 04 門控圖神經網絡GGNN

目錄 一.基礎1-[圖論、圖算法、CNN] 二.基礎2-[圖卷積神經網絡GCN] 三.torch-geometric.nn工具包安裝&#xff08;包含各種算法和數據集&#xff09; 四.GCN任務[節點分類-Cora 數據集] 五.圖注意力網絡&#xff08;GAT&#xff09; 六.圖自編碼器&#xff08;GAE&#x…

001 Configuration結構體構造

目錄DramSys 代碼分析1 Configuration結構體構造1.1 from_path 函數詳解1.2 構造過程總結這種設計的好處2 Simulator 例化過程2.1 instantiateInitiatorDramSys 代碼分析 1 Configuration結構體構造 好的&#xff0c;我們來詳細解釋一下 DRAMSysConfiguration.cpp 文件中 fro…

以太坊十年:智能合約與去中心化的崛起

以太坊10周年&#xff0c;敬開發者&#xff0c;敬構建者&#xff0c;敬還在鏈上的我們 以太坊即將迎來十周年紀念,作為一名在這個生態中深耕了8到9年的見證者&#xff0c;我親歷了它從一紙白皮書的構想到成長為全球領先去中心化平臺的全過程。這十年間&#xff0c;以太坊經歷了…