設計模式-10 - Memento Design Pattern

設計模式-10 - Memento Design Pattern?
?

1.定義


備忘錄模式是一種設計模式,它允許在不破壞封裝性的情況下捕獲和恢復對象的內部狀態。

其結構:

Originator:創建和管理備忘錄的對象。
Memento:存儲 Originator 狀態的備忘錄對象。Memento 對象是不可變的。
Caretaker:存儲 Memento 對象,而不了解其實際內容。

示例:

一個文本編輯器可以使用備忘錄模式來存儲文檔的狀態,以便用戶可以撤消和重做編輯操作。Originator 是文檔對象,Memento 是存儲文檔狀態的文本快照,Caretaker 是管理備忘錄的撤消/重做管理器。

? ? ? ? +--------------+| Originator ? |+--------------+|v+--------------+| Memento ? ? ?|+--------------+|v+--------------+| Caretaker ? ?|+--------------+|v(stores Memento)

調用關系:

  • Originator 創建一個 Memento 對象來存儲其當前狀態。
  • Caretaker 從 Originator 接收 Memento 對象并將其存儲起來。
  • Originator 修改其狀態。
  • Originator 從 Caretaker 恢復其狀態,傳遞先前創建的 Memento 對象。
  • Caretaker 將 Memento 對象傳遞給 Originator。
  • Originator 使用 Memento 對象恢復其狀態。

說明:

Originator:創建和修改其狀態,并創建 Memento 對象來存儲其狀態。
Memento:存儲 Originator 的狀態,以便以后可以恢復。
Caretaker:負責存儲和管理 Memento 對象。

?? ??? ??? ?

2.內涵

工作原理:

Originator 創建一個 Memento 對象,該對象捕獲其當前狀態。
Originator 可以將 Memento 對象傳遞給 Caretaker。
當 Originator 需要恢復其狀態時,它可以從 Caretaker 請求 Memento 對象。
Originator 使用 Memento 對象恢復其內部狀態。

3.使用示例
#include <iostream>
#include <string>
#include <vector>// Originator: The object whose state needs to be saved and restored.
class Originator {
private:std::string state;public:void SetState(const std::string& newState) {state = newState;}std::string GetState() const {return state;}// Memento: Inner class representing the state of the Originator.class Memento {private:std::string state;public:Memento(const std::string& originatorState) : state(originatorState) {}std::string GetSavedState() const {return state;}};// Create a Memento object to save the current state.Memento CreateMemento() const {return Memento(state);}// Restore the state from a Memento object.void RestoreState(const Memento& memento) {state = memento.GetSavedState();}
};// Caretaker: Manages the Memento objects.
class Caretaker {
private:std::vector<Originator::Memento> mementos;public:void AddMemento(const Originator::Memento& memento) {mementos.push_back(memento);}Originator::Memento GetMemento(int index) const {if (index >= 0 && index < mementos.size()) {return mementos[index];}throw std::out_of_range("Invalid Memento index");}
};int main() {Originator originator;Caretaker caretaker;originator.SetState("State 1");caretaker.AddMemento(originator.CreateMemento());originator.SetState("State 2");caretaker.AddMemento(originator.CreateMemento());// Restore to the previous stateoriginator.RestoreState(caretaker.GetMemento(0));std::cout << "Current state: " << originator.GetState() << std::endl;// Restore to an even earlier stateoriginator.RestoreState(caretaker.GetMemento(1));std::cout << "Current state: " << originator.GetState() << std::endl;return 0;
}

4.注意事項

備忘錄模式需要注意的事項:

  • 只存儲相關狀態:Memento 對象應僅存儲 Originator 的相關狀態,而不是其所有狀態。這有助于保持 Memento 的大小較小并提高性能。
  • 避免存儲引用:Memento 對象不應存儲對其他對象的引用,因為這可能會導致循環引用和內存泄漏。
  • 考慮序列化:如果需要在進程或計算機之間傳輸 Memento 對象,則需要考慮序列化和反序列化機制。
  • 版本控制:如果 Originator 的狀態可能會隨著時間的推移而改變,則需要考慮使用版本控制機制來管理 Memento 對象的不同版本。
  • 并發訪問:在并發環境中使用備忘錄模式時,需要確保 Originator、Memento 和 Caretaker 類都是線程安全的,并且并發訪問備忘錄是原子的。
  • 性能影響:頻繁創建和存儲 Memento 對象可能會對應用程序的性能產生影響,尤其是在處理大型或復雜的狀態時。
  • 設計復雜性:備忘錄模式可能會增加應用程序的設計復雜性,尤其是在需要管理多個 Originator 和 Memento 對象時

5.最佳實踐

當需要以下場景時,需要使用備忘錄設計模式:

  • 當需要在不破壞封裝性的情況下捕獲和恢復對象的內部狀態時。
  • 當需要多次撤消和重做操作時。
  • 當需要將復雜的對象圖存儲為快照時。

6.總結


在設計一個需要頻繁保存狀態的應用,如何確保備忘錄模式在并發環境中有效應對并發訪問,這里有些方法可以借鑒:

  • 線程安全:確保 Originator、Memento 和 Caretaker 類都是線程安全的。這可以采用多種方法實現,例如使用同步機制(例如鎖或互斥量)或使用不可變對象。
  • 只讀備忘錄:使 Memento 對象不可變。這將防止并發訪問時意外修改備忘錄的內容。
  • 并發控制:在 Caretaker 中使用適當的并發控制機制,例如讀寫鎖或原子操作,以確保對備忘錄的訪問是原子的。
  • 隔離備忘錄:為每個 Originator 實例維護一個單獨的備忘錄存儲。這將防止不同 Originator 實例之間的并發訪問沖突。
  • 使用版本控制:為備忘錄引入版本控制機制。這將允許跟蹤和恢復備忘錄的不同版本,即使在并發訪問的情況下也是如此。


其他考慮因素:

  • 性能:在高并發環境中,確保備忘錄模式的實現不會引入明顯的性能開銷。
  • 可擴展性:備忘錄模式的實現應該具有可擴展性,以便在需要時可以輕松擴展以支持更多的并發訪問。
  • 測試:徹底測試備忘錄模式的實現,以確保其在并發環境中按預期工作。

通過遵循這些準則,你可以確保備忘錄模式在需要頻繁保存狀態的并發應用程序中能有效應對并發訪問。

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

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

相關文章

品牌設計理念和logo設計方法

一 品牌設計的目的 設計是為了傳播&#xff0c;讓傳播速度更快&#xff0c;傳播效率更高&#xff0c;減少宣傳成本 二 什么是好的品牌設計 好的設計是為了讓消費者更容易看懂、記住的設計&#xff0c; 從而輔助傳播&#xff0c; 即 看得懂、記得住。 1 看得懂 就是讓別人看懂…

樹莓派|采集視頻并實時顯示畫面

1、使用SSH遠程連接到樹莓派 2、新建存放代碼的目錄 mkdir /home/pi/my_code_directory 3、進入存放代碼的目錄 cd /home/pi/my_code_directory 4、新建py文件 nano cv2test.py 5、輸入代碼 import cv2# 打開攝像頭 cap cv2.VideoCapture(0)while True:# 讀取視頻幀ret…

BGP學習二:BGP通告原則,BGP反射器,BGP路徑屬性細致講解,新手小白無負擔

目錄 一.AS號 二.BGP路由生成 1.network 2.import-route引入 三.BGP通告原則 1.只發布最優且有效的路由 2.從EBGP獲取的路由&#xff0c;會發布給所有對等體 3.水平分割原則 4.IBGP學習BGP默認不發送給EBGP&#xff0c;但如果也從IGP學習到了這條路由&#xff0c;就發…

mysql 幻讀,臟讀和不可重復讀

MySQL的臟讀、幻讀和不可重復讀是數據庫事務處理中的三種常見問題&#xff0c;它們都涉及到數據的一致性和并發性。一&#xff0c;臟讀 臟讀是指一個事務讀取了另一個事務未提交的數據。這可能導致數據不一致的問題。 例如&#xff1a; 用戶user1的初始balance是100&#xff0…

java項目之智慧圖書管理系統設計與實現(springboot+vue+mysql)

風定落花生&#xff0c;歌聲逐流水&#xff0c;大家好我是風歌&#xff0c;混跡在java圈的辛苦碼農。今天要和大家聊的是一款基于springboot的智慧圖書管理系統設計與實現。項目源碼以及部署相關請聯系風歌&#xff0c;文末附上聯系信息 。 項目簡介&#xff1a; 智慧圖書管理…

SOCKET編程(5):IO復用

IO復用 多進程/線程并發模型&#xff0c;為每個sockets分配一個進程/線程 I/O&#xff08;多路&#xff09;復用&#xff0c;采用單個進/線程就可以管理多個socket I/O復用有3種方案&#xff1a; selectpollepoll select I/O多路復用詳解 27、fd_set與FD_SETSIZE詳解 詳解…

新聞資訊微信小程序開發后端+php【附源碼,文檔說明】

博主介紹&#xff1a;?IT徐師兄、7年大廠程序員經歷。全網粉絲15W、csdn博客專家、掘金/華為云//InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精彩專欄推薦訂閱&#x1f447;&#x1f3…

管理科學SCI、SSCI雙檢索,自引率低,無預警風險,對國人相當友好!

一、期刊名稱 Journal of Organizational and End User Computing 二、期刊簡介概況 期刊類型&#xff1a;SSCI 學科領域&#xff1a;管理學 影響因子&#xff1a;6.5 中科院分區&#xff1a;2區 出版方式&#xff1a;開放出版 版面費&#xff1a;$3300 三、期刊征稿范圍…

探秘錢塘高中,筑夢未來之旅————杭州市錢塘高級中學

晨曦微露&#xff0c;書生瑯瑯&#xff0c;古韻今風交織在這方學府&#xff0c;滔滔的錢塘江畔&#xff0c;杭州市錢塘高級中學屹立于此。這所學校自1958年建校伊始&#xff0c;走過幾十年的光輝歲月&#xff0c;一直致力于提供優質的教育資源。 近年來&#xff0c;學校獲得多項…

Learning C# Programming with Unity 3D

作者&#xff1a;Alex Okita 源碼地址&#xff1a;GitHub - badkangaroo/UnityProjects: A repo for all of the projects found in the book. 全書 686 頁。

Java常見數據結構---八大結構

前言&#xff1a; 數據結構是計算機底層存儲、組織數據的方式。是指數據相互之間是以什么方式排列在一起的。 通常情況下&#xff0c;精心選擇的數據結構可以帶來更高的運行或者存儲效率 常見的八大數據結構&#xff1a; 棧&#xff1a; 思想&#xff1a; 棧是一種數據結構&…

大數據項目中的拉鏈表(hadoop,hive)

緩慢漸變維 拉鏈表 拉鏈表&#xff0c;可實現數據快照&#xff0c;可以將歷史和最新數據保存在一起 如何實現: 在原始數據增加兩個新字段 起始時間&#xff08;有效時間&#xff1a;什么時候導入的數據的時間&#xff09;&#xff0c;結束時間&#xff08;默認的結束時間為99…

運籌系列92:vrp算法包VROOM

1. 介紹 VROOM is an open-source optimization engine written in C20 that aim at providing good solutions to various real-life vehicle routing problems (VRP) within a small computing time. 可以解決如下問題&#xff1a; TSP (travelling salesman problem) CVRP …

九、 個人信息出境標準合同的簽署及備案流程是怎樣的?

為指導和幫助個人信息處理者規范有序備案個人信息出境標準合同&#xff0c;國家網信辦結合此前備案實踐經驗發布了《標準合同備案指南&#xff08;第二版&#xff09;》&#xff0c;并就個人信息出境標準合同備案的適用范圍、備案方式、備案流程和材料以及咨詢、舉報聯系方式等…

F5 BIG-IP Next Central Manager SQL注入漏洞(CVE-2024-26026、CVE-2024-21793)

0x01 產品簡介 BIG-IP Next Central Manager是BIG-IP Next的原生默認用戶界面,它可跨平臺管理BIG-IP Next實例。BIG-IP Next是F5 Networks公司推出的一款下一代BIG-IP軟件,提供了多云應用安全和應用交付服務。 0x02 漏洞概述 CVE-2024-26026:BIG-IP Next Central Manager…

產品推薦 | 基于AMD Virtex 7 FPGA VC709 的高速連接功能開發板

01 產品概述 Virtex? 7 FPGA VC709 連接功能套件是一款速率為 40Gb/s 的高速平臺&#xff0c;您可以通過評估和開發連接功能&#xff0c;迅速為包含所有必要軟硬件和 IP 核的高帶寬和高性能應用提供強大的支持。它包括一個含有 PCI Express Gen 3、Northwest Logic 公司推出的…

4.1 文本相似度(二)

目錄 1 文本相似度評估 2 代碼 2.1 load_dataset 方法 2.2 AutoTokenizer、AutoModelForSequenceClassification 1 文本相似度評估 對兩個文本拼接起來&#xff0c;然后作為一個樣本喂給模型&#xff0c;作為一個二分類的任務&#xff1b; 數據處理的方式以及訓練的基本流程…

c 指針基礎

/* 指針練習*/ #include <stdio.h> #include <stdlib.h> void printAll(int n1, int n2, int *p1, int *p2); int main(){ //賦值操作語法演示 int num1 1111; int num2 2222; int *prt1 &num1; int *prt2 &num2; printAll(num1, num2, prt1…

maven .lastUpdated文件作用

現象 有時候我在用maven管理項目時會發現有些依賴報錯&#xff0c;這時你可以看一下本地倉庫中是否有.lastUpdated文件&#xff0c;也許與它有關。 原因 有這個文件就表示依賴下載過程中發生了錯誤導致依賴沒成功下載&#xff0c;可能是網絡原因&#xff0c;也有可能是遠程…

平面設計基礎指南:從零開始的學習之旅!

平面設計師主要做什么&#xff1f; 平面設計師通過創建視覺概念來傳達信息。他們創造了從海報和廣告牌到包裝、標志和營銷材料的所有內容&#xff0c;并通過使用形狀、顏色、排版、圖像和其他元素向觀眾傳達了他們的想法。平面設計師可以在內部工作&#xff0c;專門為品牌創建…