設計模式每日硬核訓練 Day 18:備忘錄模式(Memento Pattern)完整講解與實戰應用

🔄 回顧 Day 17:中介者模式小結

在 Day 17 中,我們學習了中介者模式(Mediator Pattern):

  • 用一個中介者集中管理對象之間的通信。
  • 降低對象之間的耦合,適用于聊天系統、GUI 控件聯動、塔臺調度等。

今天進入一個非常貼近用戶操作體驗的設計模式——備忘錄模式(Memento Pattern)

備忘錄模式:在不破壞封裝的前提下,保存對象的內部狀態,便于后續恢復到某一狀態。

它是“撤銷 / 恢復”操作背后的設計思想核心。


一、備忘錄模式的應用動機

在許多軟件中,我們都可以看到“撤銷(Undo)”、“恢復(Redo)”等功能:

  • 文本編輯器可以撤銷幾次輸入
  • 游戲中可以回到某個存檔
  • 圖像處理工具支持操作歷史回退

這就要求:

  • 程序能保存某個時刻的狀態
  • 恢復時不依賴外部記錄
  • 保證對象內部狀態的私有性(封裝)

? 所以我們引入備忘錄模式:由備忘錄(Memento)保存對象狀態,管理員(Caretaker)持有備忘錄,對象(Originator)可保存/恢復。


二、結構圖(UML)

+----------------+
| Originator     |
+----------------+
| +createMemento |
| +restore(m)    |
+----------------+|v
+----------------+
| Memento        |
+----------------+
|  state         |
+----------------+^|
+----------------+
| Caretaker      |
+----------------+
|  history       |
+----------------+

在這里插入圖片描述

三、角色說明

角色說明
Originator發起人:定義要保存的狀態,并創建和恢復備忘錄
Memento備忘錄:存儲發起人對象的狀態,不提供修改接口
Caretaker管理者:保存備忘錄對象,不操作其內容,僅作管理使用

四、C++ 實現:文本編輯器 Undo 示例

我們模擬一個文本編輯器,每次輸入文本都可以保存當前狀態。

? Originator 類:TextEditor

class Memento {std::string state_;
public:Memento(const std::string& s) : state_(s) {}std::string getState() const { return state_; }
};class TextEditor {std::string text_;
public:void type(const std::string& newText) {text_ += newText;}std::shared_ptr<Memento> save() {return std::make_shared<Memento>(text_);}void restore(std::shared_ptr<Memento> m) {text_ = m->getState();}void show() const {std::cout << "當前內容:" << text_ << std::endl;}
};

? Caretaker:備忘錄棧

class Caretaker {std::stack<std::shared_ptr<Memento>> history_;
public:void backup(std::shared_ptr<Memento> m) {history_.push(m);}std::shared_ptr<Memento> undo() {if (!history_.empty()) {auto m = history_.top();history_.pop();return m;}return nullptr;}
};

? 使用示例

int main() {TextEditor editor;Caretaker caretaker;editor.type("Hello ");caretaker.backup(editor.save());editor.type("World!");caretaker.backup(editor.save());editor.type(" This should be undone.");editor.show();editor.restore(caretaker.undo());editor.show();editor.restore(caretaker.undo());editor.show();return 0;
}

輸出:

當前內容:Hello World! This should be undone.
當前內容:Hello World!
當前內容:Hello

五、實際項目中的應用場景

場景應用說明
編輯器(文本、圖像)操作歷史,撤銷恢復
游戲進度管理存檔機制,一鍵恢復到特定狀態
配置參數修改一鍵還原到默認參數或歷史設置
工作流狀態保存在流程推進過程中保存流程中間狀態
數據庫事務管理快照、事務回滾

六、優缺點分析

? 優點:

  • 保留對象狀態,支持撤銷與恢復
  • 不破壞封裝性,狀態由對象自身保存
  • 多個備份版本可管理

? 缺點:

  • 狀態快照可能占用較大內存
  • 多次保存增加性能開銷
  • 管理復雜,需注意備份何時保存/清理

七、與命令、原型模式對比

模式意圖特點
備忘錄 Memento保存對象內部狀態封裝狀態,支持恢復
命令 Command將操作封裝為對象,支持撤銷記錄操作動作,而非對象狀態本身
原型 Prototype克隆對象一般用于新對象創建,非狀態回滾

八、面試回答模板

“我們在圖像處理系統中使用備忘錄模式保存圖像編輯的中間狀態。每次用戶進行濾鏡、剪裁、調整操作時,會生成一個狀態快照,存入備忘錄棧。當用戶點擊撤銷時,恢復到上一個狀態。該方案確保封裝性,同時支持多層撤銷。”

? 強調:狀態封裝、用戶體驗、棧式回滾邏輯


九、口訣記憶

“封裝狀態不泄露,快照回滾不出錯;歷史棧中找快照,一鍵恢復沒煩惱。”


十、明日預告:Day 19

解釋器模式(Interpreter Pattern):為語言構建解釋器,對語法規則建模,實現表達式的解析與執行。

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

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

相關文章

java單元測試代碼

import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.util.List;public class UserServiceTest {Testpublic void testSearchUserByTags() {// 模擬標簽列表List<String> tagNameList List.of("tag1", "…

前端面經-VUE3篇(一)--vue3基礎知識- 插值表達式、ref、reactive

目錄 一、 插值表達式 1、插值表達式 ({{}}) 的本質與作用&#xff1a; 2、與 Vue 響應式系統關系&#xff1a; 二、指令 1、什么是 Vue 指令&#xff1f; 2、指令的分類 1、內置指令 ① 內容綁定&#xff1a;v-text 和 v-html ② 屬性綁定&#xff1a;v-bind ③ 事件綁定…

矩陣置零(中等)

可以用兩個標記數組分別記錄每一行和每一列是否有零出現。 首先遍歷該數組一次&#xff0c;如果某個元素為 0&#xff0c;那么就將該元素所在的行和列所對應標記數組的位置置為 true。然后再次遍歷該數組&#xff0c;用標記數組更新原數組。 class Solution {public void set…

Android 實現一個隱私彈窗

效果圖如下&#xff1a; 1. 設置同意、退出、點擊用戶協議、點擊隱私協議的函數參數 2. 《用戶協議》、《隱私政策》設置成可點擊的&#xff0c;且顏色要區分出來 res/layout/dialog_privacy_policy.xml 文件 <?xml version"1.0" encoding"utf-8"?&…

TCP概念+模擬tcp服務器及客戶端

目錄 一、TCP基本概念 二、ser服務器代碼 三、cil客戶端代碼 四、面試常問問題 4.1 TCP的可靠性怎么保證或怎么實現? 4.2 具體說一下滑動窗口 一、TCP基本概念 TCP&#xff08;Transmission Control Protocol&#xff0c;傳輸控制協議&#xff09;是一種面向連接的、可…

Cocos Creator 自動圖集資源 (Auto Atlas)使用注意事項

1、游戲打包時&#xff0c;自動圖集設置選項中&#xff0c;默認會刪除無關聯的圖片 2、自動圖集設置中&#xff0c;就算勾除(Remove unused ImageAsset from the Bundle)的功能&#xff0c;無關聯的圖片也不會打包進入圖集之中&#xff0c;會獨立存在打包的游戲中。 3、使用自動…

PyTorch 2.0編譯器技術深度解析:如何自動生成高性能CUDA代碼

引言&#xff1a;編譯革命的范式轉移 PyTorch 2.0的torch.compile不僅是簡單的即時編譯器&#xff08;JIT&#xff09;&#xff0c;更標志著深度學習框架從?解釋執行?到?編譯優化?的范式躍遷。本文通過逆向工程編譯過程&#xff0c;揭示PyTorch如何將動態圖轉換為高性能CU…

【AI面試準備】從0-1搭建人工智能模型自動化評估理論與測試,掌握測試數據集建立與優化,熟練數據處理和模型評測工作

面試要求&#xff1a;從0-1搭建人工智能模型自動化評估理論與測試&#xff0c;掌握測試數據集建立與優化&#xff0c;熟練數據處理和模型評測工作。 以下是針對從0-1搭建AI模型自動化評估體系的系統化知識總結&#xff0c;涵蓋核心方法論、技術棧、高頻考點及面試回答模板&…

【Linux應用】在PC的Linux環境下通過chroot運行ARM虛擬機鏡像img文件(需要依賴qemu-aarch64、不需要重新安裝iso)

【Linux應用】在PC的Linux環境下通過chroot運行ARM虛擬機鏡像img文件&#xff08;需要依賴qemu-aarch64、不需要重新安裝iso&#xff09; qemu提供了運行ARM虛擬機的方法 具體的操作方式就是建立一個硬盤img 然后通過iso安裝到img 最后再運行img即可 這種方式教程很多 很簡單 …

OpenCv實戰筆記(1)在win11搭建opencv4.11.1 + qt5.15.2 + vs2019_x64開發環境

一. 準備工作 Visual Studio 2019&#xff08;安裝時勾選 C 桌面開發 和 Windows 10 SDK&#xff09; CMake 3.20&#xff08;官網下載&#xff09; Qt 5.15.2&#xff08;下載 Qt Online Installer&#xff09;安裝時勾選 MSVC 2019 64-bit 組件。 opencv 4.11.1 源碼下載 git…

springboot+mysql+element-plus+vue完整實現汽車租賃系統

目錄 一、項目介紹 二、項目截圖 1.項目結構圖 三、系統詳細介紹 管理后臺 1.登陸頁 2.管理后臺主頁 3.汽車地點管理 4.汽車類別 5.汽車品牌 6.汽車信息 7.用戶管理 8.舉報管理 9.訂單管理 10.輪播圖管理 11.交互界面 12.圖表管理 汽車租賃商城 1.首頁 2.汽…

【算法筆記】動態規劃基礎(二):背包dp

目錄 01背包例題狀態表示狀態計算初始化AC代碼 完全背包例題狀態表示狀態計算初始化TLE代碼 多重背包例題狀態表示狀態計算初始化AC代碼 分組背包例題狀態表示狀態計算初始化AC代碼 二維費用背包例題狀態表示狀態計算初始化AC代碼 混合背包問題例題狀態表示狀態計算初始化TLE代…

Qt Quick Design 下載社區版

官方地址&#xff1a;Qt Design Studio - UI Development Tool for Applications & Devices 社區版只能用于開源軟件的開發 按圖所示下載或直接跳轉到下載頁面&#xff1a;Download Qt OSS: Get Qt Online Installerhttps://www.qt.io/download-qt-installer-oss 選Try …

深入理解CSS盒子模型

一、盒子模型的核心概念 CSS盒子模型&#xff08;Box Model&#xff09;是網頁布局的基石&#xff0c;每個HTML元素都可以看作一個矩形盒子&#xff0c;由四個同心區域構成&#xff1a; 內容區&#xff08;Content&#xff09; 內邊距&#xff08;Padding&#xff09; 邊框&a…

Python項目源碼57:數據格式轉換工具1.0(csv+json+excel+sqlite3)

1.智能路徑處理&#xff1a;自動識別并修正文件擴展名&#xff0c;根據轉換類型自動建議目標路徑&#xff0c;實時路徑格式驗證&#xff0c;自動補全缺失的文件擴展名。 2.增強型預覽功能&#xff1a;使用pandastable庫實現表格預覽&#xff0c;第三方模塊自己安裝一下&#x…

數據庫MySQL學習——day9(聚合函數與分組數據)

文章目錄 1. 聚合函數1.1 COUNT() 函數1.2 SUM() 函數1.3 AVG() 函數1.4 MIN() 函數1.5 MAX() 函數 2. GROUP BY 子句2.1 使用 GROUP BY 進行數據分組2.2 結合聚合函數 3. HAVING 子句3.1 使用 HAVING 過濾分組數據3.2 HAVING 和 WHERE 的區別 4. 實踐任務4.1 創建一個銷售表4.…

數據管理能力成熟度評估模型(DCMM)全面解析:標準深度剖析與實踐創新

文章目錄 一、DCMM模型的戰略價值與理論基礎1.1 DCMM的本質與戰略定位1.2 DCMM的理論基礎與創新點 二、DCMM模型的系統解構與邏輯分析2.1 八大能力域的有機關聯與系統架構2.2 五級成熟度模型的內在邏輯與演進規律 三、DCMM八大能力域的深度解析與實踐創新3.1 數據戰略&#xff…

Docker搜索鏡像報錯

科學上網最方便。。。。 主要是鏡像的問題 嘗試一&#xff1a; 報錯處理 Error response from daemon: Get https://index.docker.io/v1/search?qmysql&n25: dial tcp 31.13.84.2:443: i/o timeout Error response from daemon: Get https://index.docker.io/v1/se…

ERP系統源碼,java版ERP管理系統源碼,云端ERP

一套開箱即用的云端ERP系統源代碼&#xff0c;小型工廠ERP系統源碼 SaaS ERP是一套開箱即用的云端ERP系統&#xff0c;有演示&#xff0c;開發文檔&#xff0c;數據庫文檔齊全&#xff0c;自主版權落地實例&#xff0c;適合項目二開。 SaaS ERP具有高度的靈活性和可擴展性&am…

Sliding Window Attention(Longformer)

最簡單的自注意力大家肯定都會啦。 但這種全連接的自注意力&#xff08;即每個 token 需要 attend 到輸入序列中的所有其他 token&#xff09;計算與內存開銷是 O ( n 2 ) O(n^2) O(n2) 。為了緩解這個問題&#xff0c;研究者們提出了 Sliding Window Attention。 Sliding W…