設(shè)計(jì)模式中的備忘錄模式解析及相關(guān)C++實(shí)例應(yīng)用
備忘錄模式旨在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)。在命令模式中,備忘錄模式經(jīng)常還經(jīng)常被用來(lái)維護(hù)可以撤銷(Undo)操作的狀態(tài)。
類圖:

- Originator:負(fù)責(zé)創(chuàng)建一個(gè)備忘錄Memento,用以記錄當(dāng)前時(shí)刻它的內(nèi)部狀態(tài),并可使用備忘錄恢復(fù)內(nèi)部狀態(tài)。Originator可根據(jù)需要決定Memento存儲(chǔ)Originator的哪些內(nèi)部狀態(tài)。
- Memento:負(fù)責(zé)存儲(chǔ)Originator對(duì)象的內(nèi)部狀態(tài),并可防止Originator以外的其他對(duì)象訪問(wèn)備忘錄Memento。備忘錄有兩個(gè)接口,Caretaker只能看到備忘錄的窄接口,它只能將備忘錄傳遞給其他對(duì)象。Originator能夠看到一個(gè)寬接口,允許它訪問(wèn)返回到先前狀態(tài)所需的所有數(shù)據(jù)。
- Caretaker:負(fù)責(zé)保存好備忘錄Memento,不能對(duì)備忘錄的內(nèi)容進(jìn)行操作或檢查。
Memento模式中封裝的是需要保存的狀態(tài),當(dāng)需要恢復(fù)的時(shí)候才取出來(lái)進(jìn)行恢復(fù).原理很簡(jiǎn)單,實(shí)現(xiàn)的時(shí)候需要注意一個(gè)地方:窄接口和寬接口.所謂的寬接口就是一般意義上的接口,把對(duì)外的接口作為public成員;而窄接口反之,把接口作為private成員,而把需要訪問(wèn)這些接口函數(shù)的類作為這個(gè)類的友元類,也就是說(shuō)接口只暴露給了對(duì)這些接口感興趣的類,而不是暴露在外部.下面的實(shí)現(xiàn)就是窄實(shí)現(xiàn)的方法來(lái)實(shí)現(xiàn)的.
Memento模式比較適用于功能比較復(fù)雜的,但需要維護(hù)或記錄歷史屬性的類,或者需要保存的屬性只是眾多屬性中的一小部分時(shí),Originator可以根據(jù)保存的Memento信息還原到前一狀態(tài)。
如果在某個(gè)系統(tǒng)中使用命令模式時(shí),需要實(shí)現(xiàn)命令的撤銷功能,那么命令模式可以使用備忘錄模式來(lái)存儲(chǔ)可撤銷操作的狀態(tài)。
實(shí)例:
#include <iostream>
#include <string>
using namespace std;
class Memento
{
private:
string state;
public:
Memento(string state)
:state(state)
{}
string GetState()
{
return state;
}
void SetState(string state)
{
this->state = state;
}
};
class CareTaker
{
private:
Memento *memento;
public:
void SetMemento(Memento *memento)
{
this->memento = memento;
}
Memento* GetMemento()
{
return this->memento;
}
};
class Originator
{
private:
string state;
public:
Originator(string state)
{
this->state = state;
}
void RestoreMemento(Memento *memento)
{
state = memento->GetState();
}
Memento *CreateMemento()
{
return new Memento(state);
}
void SetState(string state)
{
this->state = state;
}
void ShowState()
{
cout<< this->state <<endl;
}
};
int main()
{
Originator *originator = new Originator("2012年11月11日,光棍節(jié),一個(gè)人,沒(méi)有女朋友");
CareTaker *caretaker = new CareTaker();
caretaker->SetMemento(originator->CreateMemento());
cout<<"2012年11月11日,光棍節(jié)早晨的狀態(tài)是:"<<endl;
originator->ShowState();
originator->SetState("中午參加同學(xué)婚禮去了,錦府鹽幫飯店");
originator->ShowState();
cout<<"晚上回來(lái)的狀態(tài)是"<<endl;
originator->RestoreMemento(caretaker->GetMemento());
originator->ShowState();
cout<<"跟早晨一樣,嗨"<<endl;
system("pause");
return 0;
}
輸出是這樣的

備忘錄模式適用性:
- 必須保存一個(gè)對(duì)象在某一個(gè)時(shí)刻的(部分)狀態(tài), 這樣以后需要時(shí)它才能恢復(fù)到先前的狀態(tài)。
- 如果一個(gè)用接口來(lái)讓其它對(duì)象直接得到這些狀態(tài),將會(huì)暴露對(duì)象的實(shí)現(xiàn)細(xì)節(jié)并破壞對(duì)象的封裝性。
- C++設(shè)計(jì)模式之備忘錄模式
- C++設(shè)計(jì)模式之橋接模式(Bridge)
- C++設(shè)計(jì)模式之組合模式(Composite)
- C++設(shè)計(jì)模式之享元模式(Flyweight)
- C++設(shè)計(jì)模式之策略模式(Strategy)
- C++設(shè)計(jì)模式之模板方法模式(TemplateMethod)
- C++設(shè)計(jì)模式之觀察者模式(Observer)
- C++設(shè)計(jì)模式之迭代器模式(Iterator)
- C++設(shè)計(jì)模式之適配器模式(Adapter)
- C++設(shè)計(jì)模式之備忘錄模式(Memento)
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)通訊錄的方法(包括靜態(tài)版本和動(dòng)態(tài)版本)
本文給大家分享C語(yǔ)言實(shí)現(xiàn)通訊錄的方法(包括靜態(tài)版本和動(dòng)態(tài)版本),針對(duì)每種方法給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-09-09
C++中字符串與整型及浮點(diǎn)型轉(zhuǎn)換全攻略
C++算法刷題等過(guò)程中經(jīng)常會(huì)遇到字符串與數(shù)字類型的轉(zhuǎn)換,在這其中雖然樸素的算法有不少,但是對(duì)于double等類型還是可以說(shuō)遇到一些麻煩,所以今天就來(lái)說(shuō)說(shuō)使用C++標(biāo)準(zhǔn)庫(kù)中的函數(shù)實(shí)現(xiàn)這些功能。感興趣的小伙伴一起參與閱讀吧2021-09-09
基于C++實(shí)現(xiàn)俄羅斯方塊游戲的示例代碼
俄羅斯方塊(Tetris)是一款風(fēng)靡全球的經(jīng)典益智游戲,自1984年首次發(fā)布以來(lái),便吸引了無(wú)數(shù)玩家,在這篇博文中,我們將深入探討如何用 C++ 編寫一個(gè)簡(jiǎn)單的俄羅斯方塊游戲,我們將從游戲的基本概念和設(shè)計(jì)入手,逐步實(shí)現(xiàn)游戲的各個(gè)功能模塊,感興趣小伙伴快來(lái)看看吧2024-11-11
Visual Studio2019調(diào)試DLL的實(shí)現(xiàn)
本文主要介紹了Visual Studio2019調(diào)試DLL的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01

